Signature check works
This commit is contained in:
parent
ee9c006794
commit
ed14e95d70
@ -41,7 +41,7 @@ public class BitmessageAddress {
|
||||
/**
|
||||
* Used for V4 address encryption. It's easier to just create it regardless of address version.
|
||||
*/
|
||||
private final byte[] privateEncryptionKey;
|
||||
private final byte[] pubkeyDecryptionKey;
|
||||
|
||||
private String address;
|
||||
|
||||
@ -62,7 +62,7 @@ public class BitmessageAddress {
|
||||
// for the tag, the checksum has to be created with 0x00 padding
|
||||
byte[] checksum = Security.doubleSha512(os.toByteArray(), ripe);
|
||||
this.tag = Arrays.copyOfRange(checksum, 32, 64);
|
||||
this.privateEncryptionKey = Arrays.copyOfRange(checksum, 0, 32);
|
||||
this.pubkeyDecryptionKey = Arrays.copyOfRange(checksum, 0, 32);
|
||||
// but for the address and its checksum they need to be stripped
|
||||
int offset = Bytes.numberOfLeadingZeros(ripe);
|
||||
os.write(ripe, offset, ripe.length - offset);
|
||||
@ -103,7 +103,7 @@ public class BitmessageAddress {
|
||||
}
|
||||
checksum = Security.doubleSha512(Arrays.copyOfRange(bytes, 0, counter.length()), ripe);
|
||||
this.tag = Arrays.copyOfRange(checksum, 32, 64);
|
||||
this.privateEncryptionKey = Arrays.copyOfRange(checksum, 0, 32);
|
||||
this.pubkeyDecryptionKey = Arrays.copyOfRange(checksum, 0, 32);
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
@ -135,20 +135,18 @@ public class BitmessageAddress {
|
||||
|
||||
public void setPubkey(Pubkey pubkey) {
|
||||
if (pubkey instanceof V4Pubkey) {
|
||||
try {
|
||||
V4Pubkey v4 = (V4Pubkey) pubkey;
|
||||
if (!Arrays.equals(tag, v4.getTag()))
|
||||
if (!Arrays.equals(tag, ((V4Pubkey) pubkey).getTag()))
|
||||
throw new IllegalArgumentException("Pubkey has incompatible tag");
|
||||
v4.decrypt(privateEncryptionKey);
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
if (!Arrays.equals(ripe, pubkey.getRipe()))
|
||||
throw new IllegalArgumentException("Pubkey has incompatible ripe");
|
||||
this.pubkey = pubkey;
|
||||
}
|
||||
|
||||
public byte[] getPubkeyDecryptionKey() {
|
||||
return pubkeyDecryptionKey;
|
||||
}
|
||||
|
||||
public PrivateKey getPrivateKey() {
|
||||
return privateKey;
|
||||
}
|
||||
|
@ -25,4 +25,6 @@ public interface Encrypted {
|
||||
void encrypt(byte[] publicKey) throws IOException;
|
||||
|
||||
void decrypt(byte[] privateKey) throws IOException;
|
||||
|
||||
boolean isDecrypted();
|
||||
}
|
||||
|
@ -90,6 +90,10 @@ public class ObjectMessage implements MessagePayload {
|
||||
return new InventoryVector(Bytes.truncate(Security.doubleSha512(nonce, getPayloadBytesWithoutNonce()), 32));
|
||||
}
|
||||
|
||||
private boolean isEncrypted() {
|
||||
return payload instanceof Encrypted && !((Encrypted) payload).isDecrypted();
|
||||
}
|
||||
|
||||
public boolean isSigned() {
|
||||
return payload.isSigned();
|
||||
}
|
||||
@ -103,10 +107,23 @@ public class ObjectMessage implements MessagePayload {
|
||||
|
||||
public void sign(PrivateKey key) {
|
||||
// TODO
|
||||
// Security.
|
||||
}
|
||||
|
||||
public boolean isSignatureValid() throws IOException {
|
||||
Pubkey pubkey = null; // TODO
|
||||
public void decrypt(PrivateKey key) throws IOException {
|
||||
if (payload instanceof Encrypted){
|
||||
((Encrypted) payload).decrypt(key.getPrivateEncryptionKey());
|
||||
}
|
||||
}
|
||||
|
||||
public void decrypt(byte[] privateEncryptionKey) throws IOException {
|
||||
if (payload instanceof Encrypted){
|
||||
((Encrypted) payload).decrypt(privateEncryptionKey);
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isSignatureValid(Pubkey pubkey) throws IOException {
|
||||
if (isEncrypted()) throw new IllegalStateException("Payload must be decrypted first");
|
||||
return Security.isSignatureValid(getBytesToSign(), payload.getSignature(), pubkey);
|
||||
}
|
||||
|
||||
|
@ -65,12 +65,23 @@ public class V4Pubkey extends Pubkey implements Encrypted {
|
||||
decrypted = V3Pubkey.read(encrypted.decrypt(privateKey), stream);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isDecrypted() {
|
||||
return decrypted != null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(OutputStream stream) throws IOException {
|
||||
stream.write(tag);
|
||||
encrypted.write(stream);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeBytesToSign(OutputStream out) throws IOException {
|
||||
out.write(tag);
|
||||
decrypted.writeBytesToSign(out);
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getVersion() {
|
||||
return 4;
|
||||
|
@ -22,8 +22,14 @@ import ch.dissem.bitmessage.factory.Factory;
|
||||
import ch.dissem.bitmessage.ports.ProofOfWorkEngine;
|
||||
import org.bouncycastle.asn1.x9.X9ECParameters;
|
||||
import org.bouncycastle.crypto.ec.CustomNamedCurves;
|
||||
import org.bouncycastle.jce.ECNamedCurveTable;
|
||||
import org.bouncycastle.jce.ECPointUtil;
|
||||
import org.bouncycastle.jce.provider.BouncyCastleProvider;
|
||||
import org.bouncycastle.jce.spec.ECNamedCurveSpec;
|
||||
import org.bouncycastle.jce.spec.ECParameterSpec;
|
||||
import org.bouncycastle.jce.spec.ECPublicKeySpec;
|
||||
import org.bouncycastle.math.ec.ECPoint;
|
||||
import org.bouncycastle.util.encoders.Hex;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
@ -31,9 +37,8 @@ import javax.crypto.Mac;
|
||||
import javax.crypto.spec.SecretKeySpec;
|
||||
import java.io.IOException;
|
||||
import java.math.BigInteger;
|
||||
import java.security.GeneralSecurityException;
|
||||
import java.security.MessageDigest;
|
||||
import java.security.SecureRandom;
|
||||
import java.security.*;
|
||||
import java.security.spec.KeySpec;
|
||||
import java.util.Arrays;
|
||||
|
||||
/**
|
||||
@ -181,18 +186,24 @@ public class Security {
|
||||
|
||||
public static boolean isSignatureValid(byte[] bytesToSign, byte[] signature, Pubkey pubkey) {
|
||||
ECPoint W = keyToPoint(pubkey.getSigningKey());
|
||||
// try {
|
||||
// ECParameterSpec param = null;
|
||||
// KeySpec keySpec = new ECPublicKeySpec(W, param);
|
||||
// PublicKey publicKey = KeyFactory.getInstance("ECDSA", "BC").generatePublic(keySpec);
|
||||
//
|
||||
// Signature sig = Signature.getInstance("ECDSA", "BC");
|
||||
// sig.initVerify(publicKey);
|
||||
// sig.update(bytesToSign);
|
||||
// return sig.verify(signature);
|
||||
// } catch (Exception e) {
|
||||
// throw new RuntimeException(e);
|
||||
// }
|
||||
return false; // TODO
|
||||
try {
|
||||
ECParameterSpec spec = new ECParameterSpec(
|
||||
EC_CURVE_PARAMETERS.getCurve(),
|
||||
EC_CURVE_PARAMETERS.getG(),
|
||||
EC_CURVE_PARAMETERS.getN(),
|
||||
EC_CURVE_PARAMETERS.getH(),
|
||||
EC_CURVE_PARAMETERS.getSeed()
|
||||
);
|
||||
|
||||
KeySpec keySpec = new ECPublicKeySpec(W, spec);
|
||||
PublicKey publicKey = KeyFactory.getInstance("ECDSA", "BC").generatePublic(keySpec);
|
||||
|
||||
Signature sig = Signature.getInstance("ECDSA", "BC");
|
||||
sig.initVerify(publicKey);
|
||||
sig.update(bytesToSign);
|
||||
return sig.verify(signature);
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -73,6 +73,7 @@ public class BitmessageAddressTest {
|
||||
|
||||
ObjectMessage object = TestUtils.loadObjectMessage(3, "V3Pubkey.payload");
|
||||
Pubkey pubkey = (Pubkey) object.getPayload();
|
||||
assertTrue(object.isSignatureValid(pubkey));
|
||||
address.setPubkey(pubkey);
|
||||
|
||||
assertArrayEquals(Bytes.fromHex("007402be6e76c3cb87caa946d0c003a3d4d8e1d5"), pubkey.getRipe());
|
||||
@ -80,10 +81,11 @@ public class BitmessageAddressTest {
|
||||
|
||||
@Test
|
||||
public void testV4PubkeyImport() throws IOException {
|
||||
// TODO
|
||||
ObjectMessage object = TestUtils.loadObjectMessage(4, "V4Pubkey.payload");
|
||||
V4Pubkey pubkey = (V4Pubkey) object.getPayload();
|
||||
BitmessageAddress address = new BitmessageAddress("BM-2cXxfcSetKnbHJX2Y85rSkaVpsdNUZ5q9h");
|
||||
ObjectMessage object = TestUtils.loadObjectMessage(4, "V4Pubkey.payload");
|
||||
object.decrypt(address.getPubkeyDecryptionKey());
|
||||
V4Pubkey pubkey = (V4Pubkey) object.getPayload();
|
||||
assertTrue(object.isSignatureValid(pubkey));
|
||||
address.setPubkey(pubkey);
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user