mirror of
https://github.com/status-im/ethereumj-personal.git
synced 2025-01-09 11:32:28 +00:00
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.digests.SHA256Digest;
|
||||||
import org.spongycastle.crypto.engines.AESFastEngine;
|
import org.spongycastle.crypto.engines.AESFastEngine;
|
||||||
import org.spongycastle.crypto.generators.ECKeyPairGenerator;
|
import org.spongycastle.crypto.generators.ECKeyPairGenerator;
|
||||||
import org.spongycastle.crypto.generators.KDF2BytesGenerator;
|
|
||||||
import org.spongycastle.crypto.macs.HMac;
|
import org.spongycastle.crypto.macs.HMac;
|
||||||
import org.spongycastle.crypto.modes.SICBlockCipher;
|
import org.spongycastle.crypto.modes.SICBlockCipher;
|
||||||
import org.spongycastle.crypto.params.*;
|
import org.spongycastle.crypto.params.*;
|
||||||
import org.spongycastle.math.ec.ECPoint;
|
import org.spongycastle.math.ec.ECPoint;
|
||||||
|
|
||||||
import java.io.ByteArrayInputStream;
|
import java.io.ByteArrayInputStream;
|
||||||
|
import java.io.ByteArrayOutputStream;
|
||||||
|
import java.io.IOException;
|
||||||
import java.math.BigInteger;
|
import java.math.BigInteger;
|
||||||
import java.security.SecureRandom;
|
import java.security.SecureRandom;
|
||||||
|
|
||||||
@ -24,26 +25,24 @@ import static org.ethereum.crypto.ECKey.CURVE;
|
|||||||
public class ECIESCoder {
|
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];
|
byte[] plaintext;
|
||||||
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);
|
|
||||||
|
|
||||||
plaintext = decrypt(ephem, privKey, IV, cipherBody);
|
ByteArrayInputStream is = new ByteArrayInputStream(cipher);
|
||||||
} catch (Throwable throwable) {
|
byte[] ephemBytes = new byte[2*((CURVE.getCurve().getFieldSize()+7)/8) + 1];
|
||||||
throwable.printStackTrace();
|
|
||||||
}
|
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;
|
return plaintext;
|
||||||
}
|
}
|
||||||
@ -62,23 +61,55 @@ public class ECIESCoder {
|
|||||||
byte[] d = new byte[] {};
|
byte[] d = new byte[] {};
|
||||||
byte[] e = 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 =
|
ParametersWithIV parametersWithIV =
|
||||||
new ParametersWithIV(p, IV);
|
new ParametersWithIV(p, IV);
|
||||||
|
|
||||||
iesEngine.init(false, new ECPrivateKeyParameters(prv, CURVE), new ECPublicKeyParameters(ephem, CURVE), parametersWithIV);
|
iesEngine.init(false, new ECPrivateKeyParameters(prv, CURVE), new ECPublicKeyParameters(ephem, CURVE), parametersWithIV);
|
||||||
|
|
||||||
byte[] message = iesEngine.processBlock(cipher, 0, cipher.length);
|
return iesEngine.processBlock(cipher, 0, cipher.length);
|
||||||
return message;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
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();
|
AESFastEngine aesFastEngine = new AESFastEngine();
|
||||||
|
|
||||||
EthereumIESEngine iesEngine = new EthereumIESEngine(
|
EthereumIESEngine iesEngine = new EthereumIESEngine(
|
||||||
new ECDHBasicAgreement(),
|
new ECDHBasicAgreement(),
|
||||||
new KDF2BytesGenerator(new SHA256Digest()),
|
new ConcatKDFBytesGenerator(new SHA256Digest()),
|
||||||
new HMac(new SHA256Digest()),
|
new HMac(new SHA256Digest()),
|
||||||
new SHA256Digest(),
|
new SHA256Digest(),
|
||||||
new BufferedBlockCipher(new SICBlockCipher(aesFastEngine)));
|
new BufferedBlockCipher(new SICBlockCipher(aesFastEngine)));
|
||||||
@ -87,34 +118,11 @@ public class ECIESCoder {
|
|||||||
byte[] d = new byte[] {};
|
byte[] d = new byte[] {};
|
||||||
byte[] e = new byte[] {};
|
byte[] e = new byte[] {};
|
||||||
|
|
||||||
IESParameters p = new IESWithCipherParameters(d, e, 256, MAC_KEY_SIZE);
|
IESParameters p = new IESWithCipherParameters(d, e, KEY_SIZE, KEY_SIZE);
|
||||||
ParametersWithIV parametersWithIV = new ParametersWithIV(p, new byte[256/8]);
|
ParametersWithIV parametersWithIV = new ParametersWithIV(p, IV);
|
||||||
|
|
||||||
ECKeyPairGenerator eGen = new ECKeyPairGenerator();
|
iesEngine.init(isEncrypt, new ECPrivateKeyParameters(prv, CURVE), new ECPublicKeyParameters(pub, CURVE), parametersWithIV);
|
||||||
SecureRandom random = new SecureRandom();
|
return iesEngine;
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,8 +1,10 @@
|
|||||||
package test.ethereum.crypto;
|
package test.ethereum.crypto;
|
||||||
|
|
||||||
import org.ethereum.crypto.ECIESCoder;
|
import org.ethereum.crypto.ECIESCoder;
|
||||||
|
import org.ethereum.crypto.ECKey;
|
||||||
import org.junit.Assert;
|
import org.junit.Assert;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
import org.spongycastle.math.ec.ECPoint;
|
||||||
import org.spongycastle.util.encoders.Hex;
|
import org.spongycastle.util.encoders.Hex;
|
||||||
|
|
||||||
import java.math.BigInteger;
|
import java.math.BigInteger;
|
||||||
@ -14,20 +16,40 @@ public class ECIESCoderTest {
|
|||||||
public void test1(){
|
public void test1(){
|
||||||
BigInteger privKey = new BigInteger("5e173f6ac3c669587538e7727cf19b782a4f2fda07c1eaa662c593e5e85e3051", 16);
|
BigInteger privKey = new BigInteger("5e173f6ac3c669587538e7727cf19b782a4f2fda07c1eaa662c593e5e85e3051", 16);
|
||||||
byte[] cipher = Hex.decode("049934a7b2d7f9af8fd9db941d9da281ac9381b5740e1f64f7092f3588d4f87f5ce55191a6653e5e80c1c5dd538169aa123e70dc6ffc5af1827e546c0e958e42dad355bcc1fcb9cdf2cf47ff524d2ad98cbf275e661bf4cf00960e74b5956b799771334f426df007350b46049adb21a6e78ab1408d5e6ccde6fb5e69f0f4c92bb9c725c02f99fa72b9cdc8dd53cff089e0e73317f61cc5abf6152513cb7d833f09d2851603919bf0fbe44d79a09245c6e8338eb502083dc84b846f2fee1cc310d2cc8b1b9334728f97220bb799376233e113");
|
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",
|
Assert.assertEquals("802b052f8b066640bba94a4fc39d63815c377fced6fcb84d27f791c9921ddf3e9bf0108e298f490812847109cbd778fae393e80323fd643209841a3b7f110397f37ec61d84cea03dcc5e8385db93248584e8af4b4d1c832d8c7453c0089687a700",
|
||||||
Hex.toHexString(payload));
|
Hex.toHexString(payload));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Test
|
@Test // encrypt decrypt round trip
|
||||||
public void test2(){
|
public void test2(){
|
||||||
|
|
||||||
byte[] output = ECIESCoder.encrypt("roman".getBytes());
|
BigInteger privKey = new BigInteger("5e173f6ac3c669587538e7727cf19b782a4f2fda07c1eaa662c593e5e85e3051", 16);
|
||||||
System.out.println(Hex.toHexString(output));
|
|
||||||
|
|
||||||
|
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…
x
Reference in New Issue
Block a user