Signature check works

This commit is contained in:
Christian Basler 2015-05-15 12:36:57 +02:00
parent ee9c006794
commit ed14e95d70
6 changed files with 73 additions and 32 deletions

View File

@ -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()))
throw new IllegalArgumentException("Pubkey has incompatible tag");
v4.decrypt(privateEncryptionKey);
} catch (IOException e) {
throw new RuntimeException(e);
}
if (!Arrays.equals(tag, ((V4Pubkey) pubkey).getTag()))
throw new IllegalArgumentException("Pubkey has incompatible tag");
}
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;
}

View File

@ -25,4 +25,6 @@ public interface Encrypted {
void encrypt(byte[] publicKey) throws IOException;
void decrypt(byte[] privateKey) throws IOException;
boolean isDecrypted();
}

View File

@ -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);
}

View File

@ -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;

View File

@ -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);
}
}
}

View File

@ -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);
}