Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
com.arxanfintech.common.crypto.core.ECIESCoder Maven / Gradle / Ivy
/*******************************************************************************
Copyright ArxanFintech Technology Ltd. 2018 All Rights Reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*******************************************************************************/
package com.arxanfintech.common.crypto.core;
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.SHA1Digest;
import org.spongycastle.crypto.digests.SHA256Digest;
import org.spongycastle.crypto.engines.AESFastEngine;
import org.spongycastle.crypto.generators.ECKeyPairGenerator;
import org.spongycastle.crypto.generators.EphemeralKeyPairGenerator;
import org.spongycastle.crypto.macs.HMac;
import org.spongycastle.crypto.modes.SICBlockCipher;
import org.spongycastle.crypto.params.*;
import org.spongycastle.crypto.parsers.ECIESPublicKeyParser;
import org.spongycastle.math.ec.ECPoint;
import static com.arxanfintech.common.crypto.core.ECKey.CURVE;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.math.BigInteger;
import java.security.SecureRandom;
public class ECIESCoder {
public static final int KEY_SIZE = 128;
public static byte[] decrypt(BigInteger privKey, byte[] cipher) throws IOException, InvalidCipherTextException {
return decrypt(privKey, cipher, null);
}
public static byte[] decrypt(BigInteger privKey, byte[] cipher, byte[] macData) throws IOException, InvalidCipherTextException {
byte[] plaintext;
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, macData);
return plaintext;
}
public static byte[] decrypt(ECPoint ephem, BigInteger prv, byte[] IV, byte[] cipher, byte[] macData) throws InvalidCipherTextException {
AESFastEngine aesFastEngine = new AESFastEngine();
ArxanIESEngine iesEngine = new ArxanIESEngine(
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, KEY_SIZE, KEY_SIZE);
ParametersWithIV parametersWithIV =
new ParametersWithIV(p, IV);
iesEngine.init(false, new ECPrivateKeyParameters(prv, CURVE), new ECPublicKeyParameters(ephem, CURVE), parametersWithIV);
return iesEngine.processBlock(cipher, 0, cipher.length, macData);
}
/**
* Encryption equivalent to the Crypto++ default ECIES ECP settings:
*
* DL_KeyAgreementAlgorithm: DL_KeyAgreementAlgorithm_DH struct ECPPoint,struct EnumToType enum CofactorMultiplicationOption,0
* DL_KeyDerivationAlgorithm: DL_KeyDerivationAlgorithm_P1363 struct ECPPoint,0,class P1363_KDF2 class SHA1
* DL_SymmetricEncryptionAlgorithm: DL_EncryptionAlgorithm_Xor class HMAC class SHA1 ,0
* DL_PrivateKey: DL_Key ECPPoint
* DL_PrivateKey_EC class ECP
*
* Used for Whisper V3
*
* @param privKey privKey
* @param cipher cipher
* @return decryptSimple byte[] data
* @throws IOException IOException
* @throws InvalidCipherTextException InvalidCipherTextException
*/
public static byte[] decryptSimple(BigInteger privKey, byte[] cipher) throws IOException, InvalidCipherTextException {
ArxanIESEngine iesEngine = new ArxanIESEngine(
new ECDHBasicAgreement(),
new MGF1BytesGeneratorExt(new SHA1Digest(), 1),
new HMac(new SHA1Digest()),
new SHA1Digest(),
null);
IESParameters p = new IESParameters(null, null, KEY_SIZE);
ParametersWithIV parametersWithIV = new ParametersWithIV(p, new byte[0]);
iesEngine.setHashMacKey(false);
iesEngine.init(new ECPrivateKeyParameters(privKey, CURVE), parametersWithIV,
new ECIESPublicKeyParser(ECKey.CURVE));
return iesEngine.processBlock(cipher, 0, cipher.length);
}
public static byte[] encrypt(ECPoint toPub, byte[] plaintext) throws InvalidCipherTextException, IOException{
return encrypt(toPub, plaintext, null);
}
public static byte[] encrypt(ECPoint toPub, byte[] plaintext, byte[] macData) 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();
ArxanIESEngine 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;
try {
cipher = iesEngine.processBlock(plaintext, 0, plaintext.length, macData);
ByteArrayOutputStream bos = new ByteArrayOutputStream();
byte[] pk = pub.getEncoded(false);
bos.write(pk);
bos.write(IV);
bos.write(cipher);
return bos.toByteArray();
} catch (InvalidCipherTextException e) {
throw e;
} catch (IOException e) {
throw e;
}
}
/**
* Encryption equivalent to the Crypto++ default ECIES ECP settings:
*
* DL_KeyAgreementAlgorithm: DL_KeyAgreementAlgorithm_DH struct ECPPoint,struct EnumToType enum CofactorMultiplicationOption,0
* DL_KeyDerivationAlgorithm: DL_KeyDerivationAlgorithm_P1363 struct ECPPoint,0,class P1363_KDF2 class SHA1
* DL_SymmetricEncryptionAlgorithm: DL_EncryptionAlgorithm_Xor class HMAC class SHA1,0
* DL_PrivateKey: DL_Key ECPPoint
* DL_PrivateKey_EC class ECP
*
* Used for Whisper V3
*
* @param pub
* pub
* @param plaintext
* plaintext
* @return byte[] encryptSimple
* @throws IOException
* IOException
* @throws InvalidCipherTextException
* InvalidCipherTextException
*/
public static byte[] encryptSimple(ECPoint pub, byte[] plaintext) throws IOException, InvalidCipherTextException {
ArxanIESEngine iesEngine = new ArxanIESEngine(
new ECDHBasicAgreement(),
new MGF1BytesGeneratorExt(new SHA1Digest(), 1),
new HMac(new SHA1Digest()),
new SHA1Digest(),
null);
IESParameters p = new IESParameters(null, null, KEY_SIZE);
ParametersWithIV parametersWithIV = new ParametersWithIV(p, new byte[0]);
iesEngine.setHashMacKey(false);
ECKeyPairGenerator eGen = new ECKeyPairGenerator();
SecureRandom random = new SecureRandom();
KeyGenerationParameters gParam = new ECKeyGenerationParameters(CURVE, random);
eGen.init(gParam);
// AsymmetricCipherKeyPairGenerator testGen = new AsymmetricCipherKeyPairGenerator() {
// ECKey priv = ECKey.fromPrivate(Hex.decode("d0b043b4c5d657670778242d82d68a29d25d7d711127d17b8e299f156dad361a"));
//
// @Override
// public void init(KeyGenerationParameters keyGenerationParameters) {
// }
//
// @Override
// public AsymmetricCipherKeyPair generateKeyPair() {
// return new AsymmetricCipherKeyPair(new ECPublicKeyParameters(priv.getPubKeyPoint(), CURVE),
// new ECPrivateKeyParameters(priv.getPrivKey(), CURVE));
// }
// };
EphemeralKeyPairGenerator ephemeralKeyPairGenerator =
new EphemeralKeyPairGenerator(/*testGen*/eGen, new ECIESPublicKeyEncoder());
iesEngine.init(new ECPublicKeyParameters(pub, CURVE), parametersWithIV, ephemeralKeyPairGenerator);
return iesEngine.processBlock(plaintext, 0, plaintext.length);
}
private static ArxanIESEngine makeIESEngine(boolean isEncrypt, ECPoint pub, BigInteger prv, byte[] IV) {
AESFastEngine aesFastEngine = new AESFastEngine();
ArxanIESEngine iesEngine = new ArxanIESEngine(
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, KEY_SIZE, KEY_SIZE);
ParametersWithIV parametersWithIV = new ParametersWithIV(p, IV);
iesEngine.init(isEncrypt, new ECPrivateKeyParameters(prv, CURVE), new ECPublicKeyParameters(pub, CURVE), parametersWithIV);
return iesEngine;
}
public static int getOverhead() {
// 256 bit EC public key, IV, 256 bit MAC
return 65 + KEY_SIZE/8 + 32;
}
}