Test encode/decode round trip with ECIESCoder
This commit is contained in:
parent
4b51c8dd80
commit
7c2bae4524
|
@ -9,13 +9,14 @@ import org.spongycastle.crypto.agreement.ECDHBasicAgreement;
|
|||
import org.spongycastle.crypto.digests.SHA256Digest;
|
||||
import org.spongycastle.crypto.engines.AESFastEngine;
|
||||
import org.spongycastle.crypto.generators.ECKeyPairGenerator;
|
||||
import org.spongycastle.crypto.generators.KDF2BytesGenerator;
|
||||
import org.spongycastle.crypto.macs.HMac;
|
||||
import org.spongycastle.crypto.modes.SICBlockCipher;
|
||||
import org.spongycastle.crypto.params.*;
|
||||
import org.spongycastle.math.ec.ECPoint;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.math.BigInteger;
|
||||
import java.security.SecureRandom;
|
||||
|
||||
|
@ -24,26 +25,24 @@ import static org.ethereum.crypto.ECKey.CURVE;
|
|||
public class ECIESCoder {
|
||||
|
||||
|
||||
public static final int MAC_KEY_SIZE = 128;
|
||||
public static final int KEY_SIZE = 128;
|
||||
|
||||
|
||||
public static byte[] decrypt(BigInteger privKey, byte[] cipher) {
|
||||
public static byte[] decrypt(BigInteger privKey, byte[] cipher) throws Throwable {
|
||||
|
||||
byte[] plaintext = new byte[0];
|
||||
try {
|
||||
ByteArrayInputStream is = new ByteArrayInputStream(cipher);
|
||||
byte[] ephemBytes = new byte[2*((CURVE.getCurve().getFieldSize()+7)/8) + 1];
|
||||
is.read(ephemBytes);
|
||||
ECPoint ephem = CURVE.getCurve().decodePoint(ephemBytes);
|
||||
byte[] IV = new byte[MAC_KEY_SIZE/8];
|
||||
is.read(IV);
|
||||
byte[] cipherBody = new byte[is.available()];
|
||||
is.read(cipherBody);
|
||||
byte[] plaintext;
|
||||
|
||||
plaintext = decrypt(ephem, privKey, IV, cipherBody);
|
||||
} catch (Throwable throwable) {
|
||||
throwable.printStackTrace();
|
||||
}
|
||||
ByteArrayInputStream is = new ByteArrayInputStream(cipher);
|
||||
byte[] ephemBytes = new byte[2*((CURVE.getCurve().getFieldSize()+7)/8) + 1];
|
||||
|
||||
is.read(ephemBytes);
|
||||
ECPoint ephem = CURVE.getCurve().decodePoint(ephemBytes);
|
||||
byte[] IV = new byte[KEY_SIZE /8];
|
||||
is.read(IV);
|
||||
byte[] cipherBody = new byte[is.available()];
|
||||
is.read(cipherBody);
|
||||
|
||||
plaintext = decrypt(ephem, privKey, IV, cipherBody);
|
||||
|
||||
return plaintext;
|
||||
}
|
||||
|
@ -62,23 +61,55 @@ public class ECIESCoder {
|
|||
byte[] d = new byte[] {};
|
||||
byte[] e = new byte[] {};
|
||||
|
||||
IESParameters p = new IESWithCipherParameters(d, e, MAC_KEY_SIZE, MAC_KEY_SIZE);
|
||||
IESParameters p = new IESWithCipherParameters(d, e, KEY_SIZE, KEY_SIZE);
|
||||
ParametersWithIV parametersWithIV =
|
||||
new ParametersWithIV(p, IV);
|
||||
|
||||
iesEngine.init(false, new ECPrivateKeyParameters(prv, CURVE), new ECPublicKeyParameters(ephem, CURVE), parametersWithIV);
|
||||
|
||||
byte[] message = iesEngine.processBlock(cipher, 0, cipher.length);
|
||||
return message;
|
||||
return iesEngine.processBlock(cipher, 0, cipher.length);
|
||||
}
|
||||
|
||||
|
||||
public static byte[] encrypt(byte[] plaintext) {
|
||||
public static byte[] encrypt(ECPoint toPub, byte[] plaintext) throws InvalidCipherTextException, IOException {
|
||||
|
||||
ECKeyPairGenerator eGen = new ECKeyPairGenerator();
|
||||
SecureRandom random = new SecureRandom();
|
||||
KeyGenerationParameters gParam = new ECKeyGenerationParameters(CURVE, random);
|
||||
|
||||
eGen.init(gParam);
|
||||
|
||||
byte[] IV = new byte[KEY_SIZE/8];
|
||||
new SecureRandom().nextBytes(IV);
|
||||
|
||||
AsymmetricCipherKeyPair ephemPair = eGen.generateKeyPair();
|
||||
BigInteger prv = ((ECPrivateKeyParameters)ephemPair.getPrivate()).getD();
|
||||
ECPoint pub = ((ECPublicKeyParameters)ephemPair.getPublic()).getQ();
|
||||
EthereumIESEngine iesEngine = makeIESEngine(true, toPub, prv, IV);
|
||||
|
||||
|
||||
ECKeyGenerationParameters keygenParams = new ECKeyGenerationParameters(CURVE, random);
|
||||
ECKeyPairGenerator generator = new ECKeyPairGenerator();
|
||||
generator.init(keygenParams);
|
||||
|
||||
ECKeyPairGenerator gen = new ECKeyPairGenerator();
|
||||
gen.init(new ECKeyGenerationParameters(ECKey.CURVE, random));
|
||||
|
||||
byte[] cipher = iesEngine.processBlock(plaintext, 0, plaintext.length);
|
||||
ByteArrayOutputStream bos = new ByteArrayOutputStream();
|
||||
bos.write(pub.getEncoded(false));
|
||||
bos.write(IV);
|
||||
bos.write(cipher);
|
||||
return bos.toByteArray();
|
||||
}
|
||||
|
||||
|
||||
private static EthereumIESEngine makeIESEngine(boolean isEncrypt, ECPoint pub, BigInteger prv, byte[] IV) {
|
||||
AESFastEngine aesFastEngine = new AESFastEngine();
|
||||
|
||||
EthereumIESEngine iesEngine = new EthereumIESEngine(
|
||||
new ECDHBasicAgreement(),
|
||||
new KDF2BytesGenerator(new SHA256Digest()),
|
||||
new ConcatKDFBytesGenerator(new SHA256Digest()),
|
||||
new HMac(new SHA256Digest()),
|
||||
new SHA256Digest(),
|
||||
new BufferedBlockCipher(new SICBlockCipher(aesFastEngine)));
|
||||
|
@ -87,34 +118,11 @@ public class ECIESCoder {
|
|||
byte[] d = new byte[] {};
|
||||
byte[] e = new byte[] {};
|
||||
|
||||
IESParameters p = new IESWithCipherParameters(d, e, 256, MAC_KEY_SIZE);
|
||||
ParametersWithIV parametersWithIV = new ParametersWithIV(p, new byte[256/8]);
|
||||
IESParameters p = new IESWithCipherParameters(d, e, KEY_SIZE, KEY_SIZE);
|
||||
ParametersWithIV parametersWithIV = new ParametersWithIV(p, IV);
|
||||
|
||||
ECKeyPairGenerator eGen = new ECKeyPairGenerator();
|
||||
SecureRandom random = new SecureRandom();
|
||||
KeyGenerationParameters gParam = new ECKeyGenerationParameters(CURVE, random);
|
||||
|
||||
eGen.init(gParam);
|
||||
|
||||
|
||||
AsymmetricCipherKeyPair p1 = eGen.generateKeyPair();
|
||||
AsymmetricCipherKeyPair p2 = eGen.generateKeyPair();
|
||||
|
||||
|
||||
ECKeyGenerationParameters keygenParams = new ECKeyGenerationParameters(CURVE, random);
|
||||
ECKeyPairGenerator generator = new ECKeyPairGenerator();
|
||||
generator.init(keygenParams);
|
||||
|
||||
ECKeyPairGenerator gen = new ECKeyPairGenerator();
|
||||
gen.init(new ECKeyGenerationParameters(CURVE, random));
|
||||
|
||||
iesEngine.init(true, p1.getPrivate(), p2.getPublic(), parametersWithIV);
|
||||
|
||||
byte[] cipher = new byte[0];
|
||||
try {
|
||||
cipher = iesEngine.processBlock(plaintext, 0, plaintext.length);
|
||||
} catch (InvalidCipherTextException e1) {e1.printStackTrace();}
|
||||
return cipher;
|
||||
iesEngine.init(isEncrypt, new ECPrivateKeyParameters(prv, CURVE), new ECPublicKeyParameters(pub, CURVE), parametersWithIV);
|
||||
return iesEngine;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,8 +1,10 @@
|
|||
package test.ethereum.crypto;
|
||||
|
||||
import org.ethereum.crypto.ECIESCoder;
|
||||
import org.ethereum.crypto.ECKey;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
import org.spongycastle.math.ec.ECPoint;
|
||||
import org.spongycastle.util.encoders.Hex;
|
||||
|
||||
import java.math.BigInteger;
|
||||
|
@ -14,20 +16,40 @@ public class ECIESCoderTest {
|
|||
public void test1(){
|
||||
BigInteger privKey = new BigInteger("5e173f6ac3c669587538e7727cf19b782a4f2fda07c1eaa662c593e5e85e3051", 16);
|
||||
byte[] cipher = Hex.decode("049934a7b2d7f9af8fd9db941d9da281ac9381b5740e1f64f7092f3588d4f87f5ce55191a6653e5e80c1c5dd538169aa123e70dc6ffc5af1827e546c0e958e42dad355bcc1fcb9cdf2cf47ff524d2ad98cbf275e661bf4cf00960e74b5956b799771334f426df007350b46049adb21a6e78ab1408d5e6ccde6fb5e69f0f4c92bb9c725c02f99fa72b9cdc8dd53cff089e0e73317f61cc5abf6152513cb7d833f09d2851603919bf0fbe44d79a09245c6e8338eb502083dc84b846f2fee1cc310d2cc8b1b9334728f97220bb799376233e113");
|
||||
byte[] payload = ECIESCoder.decrypt(privKey, cipher);
|
||||
|
||||
byte[] payload = new byte[0];
|
||||
try {
|
||||
payload = ECIESCoder.decrypt(privKey, cipher);
|
||||
} catch (Throwable e) {e.printStackTrace();}
|
||||
|
||||
Assert.assertEquals("802b052f8b066640bba94a4fc39d63815c377fced6fcb84d27f791c9921ddf3e9bf0108e298f490812847109cbd778fae393e80323fd643209841a3b7f110397f37ec61d84cea03dcc5e8385db93248584e8af4b4d1c832d8c7453c0089687a700",
|
||||
Hex.toHexString(payload));
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
@Test // encrypt decrypt round trip
|
||||
public void test2(){
|
||||
|
||||
byte[] output = ECIESCoder.encrypt("roman".getBytes());
|
||||
System.out.println(Hex.toHexString(output));
|
||||
BigInteger privKey = new BigInteger("5e173f6ac3c669587538e7727cf19b782a4f2fda07c1eaa662c593e5e85e3051", 16);
|
||||
|
||||
byte[] payload = Hex.decode("1122334455");
|
||||
|
||||
ECKey ecKey = ECKey.fromPrivate(privKey);
|
||||
ECPoint pubKeyPoint = ecKey.getPubKeyPoint();
|
||||
|
||||
byte[] cipher = new byte[0];
|
||||
try {
|
||||
cipher = ECIESCoder.encrypt(pubKeyPoint, payload);
|
||||
} catch (Throwable e) {e.printStackTrace();}
|
||||
|
||||
System.out.println(Hex.toHexString(cipher));
|
||||
|
||||
byte[] decrypted_payload = new byte[0];
|
||||
try {
|
||||
decrypted_payload = ECIESCoder.decrypt(privKey, cipher);
|
||||
} catch (Throwable e) {e.printStackTrace();}
|
||||
|
||||
System.out.println(Hex.toHexString(decrypted_payload));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue