Introduce Coder/Decoder for ECIES
This commit is contained in:
parent
18994693e6
commit
b0548ea0ae
|
@ -0,0 +1,120 @@
|
|||
package org.ethereum.crypto;
|
||||
|
||||
import org.ethereum.ConcatKDFBytesGenerator;
|
||||
import org.spongycastle.crypto.AsymmetricCipherKeyPair;
|
||||
import org.spongycastle.crypto.BufferedBlockCipher;
|
||||
import org.spongycastle.crypto.InvalidCipherTextException;
|
||||
import org.spongycastle.crypto.KeyGenerationParameters;
|
||||
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.math.BigInteger;
|
||||
import java.security.SecureRandom;
|
||||
|
||||
import static org.ethereum.crypto.ECKey.CURVE;
|
||||
|
||||
public class ECIESCoder {
|
||||
|
||||
|
||||
public static final int MAC_KEY_SIZE = 128;
|
||||
|
||||
|
||||
public static byte[] decrypt(BigInteger privKey, byte[] cipher) {
|
||||
|
||||
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);
|
||||
|
||||
plaintext = decrypt(ephem, privKey, IV, cipherBody);
|
||||
} catch (Throwable throwable) {
|
||||
throwable.printStackTrace();
|
||||
}
|
||||
|
||||
return plaintext;
|
||||
}
|
||||
|
||||
public static byte[] decrypt(ECPoint ephem, BigInteger prv, byte[] IV, byte[] cipher) throws Throwable {
|
||||
AESFastEngine aesFastEngine = new AESFastEngine();
|
||||
|
||||
EthereumIESEngine iesEngine = new EthereumIESEngine(
|
||||
new ECDHBasicAgreement(),
|
||||
new ConcatKDFBytesGenerator(new SHA256Digest()),
|
||||
new HMac(new SHA256Digest()),
|
||||
new SHA256Digest(),
|
||||
new BufferedBlockCipher(new SICBlockCipher(aesFastEngine)));
|
||||
|
||||
|
||||
byte[] d = new byte[] {};
|
||||
byte[] e = new byte[] {};
|
||||
|
||||
IESParameters p = new IESWithCipherParameters(d, e, MAC_KEY_SIZE, MAC_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;
|
||||
}
|
||||
|
||||
|
||||
public static byte[] encrypt(byte[] plaintext) {
|
||||
AESFastEngine aesFastEngine = new AESFastEngine();
|
||||
|
||||
EthereumIESEngine iesEngine = new EthereumIESEngine(
|
||||
new ECDHBasicAgreement(),
|
||||
new KDF2BytesGenerator(new SHA256Digest()),
|
||||
new HMac(new SHA256Digest()),
|
||||
new SHA256Digest(),
|
||||
new BufferedBlockCipher(new SICBlockCipher(aesFastEngine)));
|
||||
|
||||
|
||||
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]);
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,33 @@
|
|||
package test.ethereum.crypto;
|
||||
|
||||
import org.ethereum.crypto.ECIESCoder;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
import org.spongycastle.util.encoders.Hex;
|
||||
|
||||
import java.math.BigInteger;
|
||||
|
||||
public class ECIESCoderTest {
|
||||
|
||||
|
||||
@Test // decrypt cpp data
|
||||
public void test1(){
|
||||
BigInteger privKey = new BigInteger("5e173f6ac3c669587538e7727cf19b782a4f2fda07c1eaa662c593e5e85e3051", 16);
|
||||
byte[] cipher = Hex.decode("049934a7b2d7f9af8fd9db941d9da281ac9381b5740e1f64f7092f3588d4f87f5ce55191a6653e5e80c1c5dd538169aa123e70dc6ffc5af1827e546c0e958e42dad355bcc1fcb9cdf2cf47ff524d2ad98cbf275e661bf4cf00960e74b5956b799771334f426df007350b46049adb21a6e78ab1408d5e6ccde6fb5e69f0f4c92bb9c725c02f99fa72b9cdc8dd53cff089e0e73317f61cc5abf6152513cb7d833f09d2851603919bf0fbe44d79a09245c6e8338eb502083dc84b846f2fee1cc310d2cc8b1b9334728f97220bb799376233e113");
|
||||
byte[] payload = ECIESCoder.decrypt(privKey, cipher);
|
||||
|
||||
|
||||
Assert.assertEquals("802b052f8b066640bba94a4fc39d63815c377fced6fcb84d27f791c9921ddf3e9bf0108e298f490812847109cbd778fae393e80323fd643209841a3b7f110397f37ec61d84cea03dcc5e8385db93248584e8af4b4d1c832d8c7453c0089687a700",
|
||||
Hex.toHexString(payload));
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void test2(){
|
||||
|
||||
byte[] output = ECIESCoder.encrypt("roman".getBytes());
|
||||
System.out.println(Hex.toHexString(output));
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -140,4 +140,5 @@ public class ECIESTest {
|
|||
byte[] cipher = iesEngine.processBlock(plaintext, 0, plaintext.length);
|
||||
return cipher;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue