@@ -49,7 +49,6 @@ public class ED25519SignatureFunction implements SignatureFunction { | |||
} | |||
// 调用ED25519签名算法计算签名结果 | |||
// return new SignatureDigest(ED25519, Ed25519Utils.sign_512(data, rawPrivKeyBytes)); | |||
return new SignatureDigest(ED25519, ED25519Utils.sign(data, rawPrivKeyBytes)); | |||
} | |||
@@ -76,7 +75,6 @@ public class ED25519SignatureFunction implements SignatureFunction { | |||
} | |||
// 调用ED25519验签算法验证签名结果 | |||
// return Ed25519Utils.verify(data, rawPubKeyBytes, rawDigestBytes); | |||
return ED25519Utils.verify(data, rawPubKeyBytes, rawDigestBytes); | |||
} | |||
@@ -84,21 +82,8 @@ public class ED25519SignatureFunction implements SignatureFunction { | |||
public PubKey retrievePubKey(PrivKey privKey) { | |||
byte[] rawPrivKeyBytes = privKey.getRawKeyBytes(); | |||
byte[] rawPubKeyBytes = ED25519Utils.retrievePublicKey(rawPrivKeyBytes); | |||
// EdDSAParameterSpec spec = EdDSANamedCurveTable.getByName(EdDSANamedCurveTable.CURVE_ED25519_SHA512); | |||
// EdDSAPrivateKeySpec privateKeySpec = new EdDSAPrivateKeySpec(rawPrivKeyBytes, spec); | |||
// byte[] rawPubKeyBytes = privateKeySpec.getA().toByteArray(); | |||
return new PubKey(ED25519, rawPubKeyBytes); | |||
} | |||
// | |||
// @Override | |||
// public byte[] retrievePubKey(byte[] privKeyBytes) { | |||
// | |||
// byte[] rawPrivKeyBytes = resolvePrivKey(privKeyBytes).getRawKeyBytes(); | |||
// EdDSAParameterSpec spec = EdDSANamedCurveTable.getByName(EdDSANamedCurveTable.CURVE_ED25519_SHA512); | |||
// EdDSAPrivateKeySpec privateKeySpec = new EdDSAPrivateKeySpec(rawPrivKeyBytes, spec); | |||
// byte[] rawPubKeyBytes = privateKeySpec.getA().toByteArray(); | |||
// return new PubKey(ED25519, rawPubKeyBytes).toBytes(); | |||
// } | |||
@Override | |||
public boolean supportPrivKey(byte[] privKeyBytes) { | |||
@@ -112,7 +97,7 @@ public class ED25519SignatureFunction implements SignatureFunction { | |||
if (supportPrivKey(privKeyBytes)) { | |||
return new PrivKey(privKeyBytes); | |||
} else { | |||
throw new CryptoException("privKeyBytes is invalid!"); | |||
throw new CryptoException("privKeyBytes are invalid!"); | |||
} | |||
} | |||
@@ -129,7 +114,7 @@ public class ED25519SignatureFunction implements SignatureFunction { | |||
if (supportPubKey(pubKeyBytes)) { | |||
return new PubKey(pubKeyBytes); | |||
} else { | |||
throw new CryptoException("pubKeyBytes is invalid!"); | |||
throw new CryptoException("pubKeyBytes are invalid!"); | |||
} | |||
} | |||
@@ -144,7 +129,7 @@ public class ED25519SignatureFunction implements SignatureFunction { | |||
if (supportDigest(digestBytes)) { | |||
return new SignatureDigest(digestBytes); | |||
} else { | |||
throw new CryptoException("digestBytes is invalid!"); | |||
throw new CryptoException("digestBytes are invalid!"); | |||
} | |||
} | |||
@@ -162,11 +147,6 @@ public class ED25519SignatureFunction implements SignatureFunction { | |||
byte[] privKeyBytes = privKeyParams.getEncoded(); | |||
byte[] pubKeyBytes = pubKeyParams.getEncoded(); | |||
// KeyPairGenerator keyPairGenerator = new KeyPairGenerator(); | |||
// KeyPair keyPair = keyPairGenerator.generateKeyPair(); | |||
// EdDSAPrivateKey privKey = (EdDSAPrivateKey) keyPair.getPrivate(); | |||
// EdDSAPublicKey pubKey = (EdDSAPublicKey) keyPair.getPublic(); | |||
// return new CryptoKeyPair(new PubKey(ED25519, pubKey.getAbyte()), new PrivKey(ED25519, privKey.getSeed())); | |||
return new AsymmetricKeypair(new PubKey(ED25519, pubKeyBytes), new PrivKey(ED25519, privKeyBytes)); | |||
} | |||
@@ -9,6 +9,7 @@ import com.jd.blockchain.crypto.CryptoBytes; | |||
import com.jd.blockchain.crypto.CryptoException; | |||
import com.jd.blockchain.crypto.HashDigest; | |||
import com.jd.blockchain.crypto.HashFunction; | |||
import com.jd.blockchain.crypto.utils.classic.RIPEMD160Utils; | |||
import com.jd.blockchain.utils.security.RipeMD160Utils; | |||
public class RIPEMD160HashFunction implements HashFunction { | |||
@@ -34,7 +35,7 @@ public class RIPEMD160HashFunction implements HashFunction { | |||
throw new CryptoException("data is null!"); | |||
} | |||
byte[] digestBytes = RipeMD160Utils.hash(data); | |||
byte[] digestBytes = RIPEMD160Utils.hash(data); | |||
return new HashDigest(RIPEMD160, digestBytes); | |||
} | |||
@@ -9,6 +9,7 @@ import com.jd.blockchain.crypto.CryptoBytes; | |||
import com.jd.blockchain.crypto.CryptoException; | |||
import com.jd.blockchain.crypto.HashDigest; | |||
import com.jd.blockchain.crypto.HashFunction; | |||
import com.jd.blockchain.crypto.utils.classic.SHA256Utils; | |||
import com.jd.blockchain.utils.security.ShaUtils; | |||
public class SHA256HashFunction implements HashFunction { | |||
@@ -34,7 +35,7 @@ public class SHA256HashFunction implements HashFunction { | |||
throw new CryptoException("data is null!"); | |||
} | |||
byte[] digestBytes = ShaUtils.hash_256(data); | |||
byte[] digestBytes = SHA256Utils.hash(data); | |||
return new HashDigest(SHA256, digestBytes); | |||
} | |||
@@ -0,0 +1,10 @@ | |||
package com.jd.blockchain.crypto.utils.classic; | |||
/** | |||
* @author zhanglin33 | |||
* @title: AESUtils | |||
* @description: AES/CBC/PKCS7Padding symmetric encryption algorithm | |||
* @date 2019-04-22, 09:37 | |||
*/ | |||
public class AESUtils { | |||
} |
@@ -114,9 +114,8 @@ public class RSAUtils { | |||
try { | |||
return signer.generateSignature(); | |||
} catch (CryptoException e) { | |||
e.printStackTrace(); | |||
throw new com.jd.blockchain.crypto.CryptoException(e.getMessage(), e); | |||
} | |||
return null; | |||
} | |||
/** | |||
@@ -177,14 +176,14 @@ public class RSAUtils { | |||
encryptor.init(true, params); | |||
try { | |||
for (int i= 0; i < blockNum; i++) { | |||
inputLength = ((plainBytes.length - i * PLAINTEXT_BLOCKSIZE) > i * PLAINTEXT_BLOCKSIZE)? | |||
inputLength = ((plainBytes.length - i * PLAINTEXT_BLOCKSIZE) > PLAINTEXT_BLOCKSIZE)? | |||
PLAINTEXT_BLOCKSIZE : (plainBytes.length - i * PLAINTEXT_BLOCKSIZE); | |||
buffer = encryptor.processBlock(plainBytes, i * PLAINTEXT_BLOCKSIZE, inputLength); | |||
System.arraycopy(buffer,0, | |||
result, i * CIPHERTEXT_BLOCKSIZE, CIPHERTEXT_BLOCKSIZE); | |||
} | |||
} catch (InvalidCipherTextException e) { | |||
e.printStackTrace(); | |||
throw new com.jd.blockchain.crypto.CryptoException(e.getMessage(), e); | |||
} | |||
return result; | |||
} | |||
@@ -274,19 +273,8 @@ public class RSAUtils { | |||
BigInteger modulus = pubKey.getModulus(); | |||
BigInteger exponent = pubKey.getExponent(); | |||
byte[] modulusBytes = new byte[MODULUS_LENGTH]; | |||
byte[] exponentBytes = exponent.toByteArray(); | |||
byte[] encodedModulusBytes = modulus.toByteArray(); | |||
int encodedModulusLength = encodedModulusBytes.length; | |||
if (encodedModulusLength > MODULUS_LENGTH) { | |||
System.arraycopy(encodedModulusBytes,encodedModulusLength - MODULUS_LENGTH, | |||
modulusBytes,0, MODULUS_LENGTH); | |||
} else { | |||
System.arraycopy(encodedModulusBytes,0, | |||
modulusBytes,MODULUS_LENGTH - encodedModulusLength, MODULUS_LENGTH); | |||
} | |||
byte[] modulusBytes = bigInteger2Bytes(modulus,MODULUS_LENGTH); | |||
return BytesUtils.concat(modulusBytes,exponentBytes); | |||
} | |||
@@ -309,15 +297,14 @@ public class RSAUtils { | |||
try { | |||
keyFactory = KeyFactory.getInstance("RSA"); | |||
} catch (NoSuchAlgorithmException e) { | |||
e.printStackTrace(); | |||
throw new com.jd.blockchain.crypto.CryptoException(e.getMessage(), e); | |||
} | |||
RSAPublicKey publicKey = null; | |||
try { | |||
assert keyFactory != null; | |||
publicKey = (RSAPublicKey) keyFactory.generatePublic(keySpec); | |||
} catch (InvalidKeySpecException e) { | |||
e.printStackTrace(); | |||
throw new com.jd.blockchain.crypto.CryptoException(e.getMessage(), e); | |||
} | |||
assert publicKey != null; | |||
@@ -416,86 +403,15 @@ public class RSAUtils { | |||
BigInteger dQ = privKey.getDQ(); | |||
BigInteger qInv = privKey.getQInv(); | |||
byte[] modulusBytes = new byte[MODULUS_LENGTH]; | |||
byte[] modulusBytes = bigInteger2Bytes(modulus,MODULUS_LENGTH); | |||
byte[] pubExpBytes = pubExp.toByteArray(); | |||
byte[] privExpBytes = new byte[PRIVEXP_LENGTH]; | |||
byte[] pBytes = new byte[P_LENGTH]; | |||
byte[] qBytes = new byte[Q_LENGTH]; | |||
byte[] dPBytes = new byte[DP_LENGTH]; | |||
byte[] dQBytes = new byte[DQ_LENGTH]; | |||
byte[] qInvBytes = new byte[QINV_LENGTH]; | |||
byte[] encodedModulusBytes = modulus.toByteArray(); | |||
byte[] encodedPrivExpBytes = privExp.toByteArray(); | |||
byte[] encodedPBytes = p.toByteArray(); | |||
byte[] encodedQBytes = q.toByteArray(); | |||
byte[] encodedDPBytes = dP.toByteArray(); | |||
byte[] encodedDQBytes = dQ.toByteArray(); | |||
byte[] encodedQInvBytes = qInv.toByteArray(); | |||
int encodedModulusLength = encodedModulusBytes.length; | |||
int encodedPrivExpBytesLength = encodedPrivExpBytes.length; | |||
int encodedPBytesLength = encodedPBytes.length; | |||
int encodedQBytesLength = encodedQBytes.length; | |||
int encodedDPBytesLength = encodedDPBytes.length; | |||
int encodedDQBytesLength = encodedDQBytes.length; | |||
int encodedQInvBytesLength = encodedQInvBytes.length; | |||
if (encodedModulusLength > MODULUS_LENGTH) { | |||
System.arraycopy(encodedModulusBytes,encodedModulusLength - MODULUS_LENGTH, | |||
modulusBytes,0, MODULUS_LENGTH); | |||
} else { | |||
System.arraycopy(encodedModulusBytes,0, | |||
modulusBytes,MODULUS_LENGTH - encodedModulusLength, MODULUS_LENGTH); | |||
} | |||
if (encodedPrivExpBytesLength > PRIVEXP_LENGTH) { | |||
System.arraycopy(encodedPrivExpBytes,encodedPrivExpBytesLength - PRIVEXP_LENGTH, | |||
privExpBytes,0, PRIVEXP_LENGTH); | |||
} else { | |||
System.arraycopy(encodedPrivExpBytes,0, | |||
privExpBytes,PRIVEXP_LENGTH - encodedPrivExpBytesLength, PRIVEXP_LENGTH); | |||
} | |||
if (encodedPBytesLength > P_LENGTH) { | |||
System.arraycopy(encodedPBytes,encodedPBytesLength - P_LENGTH, | |||
pBytes,0, P_LENGTH); | |||
} else { | |||
System.arraycopy(encodedPBytes,0, | |||
pBytes,P_LENGTH - encodedPBytesLength, P_LENGTH); | |||
} | |||
if (encodedQBytesLength > Q_LENGTH) { | |||
System.arraycopy(encodedQBytes,encodedQBytesLength - Q_LENGTH, | |||
qBytes,0, Q_LENGTH); | |||
} else { | |||
System.arraycopy(encodedQBytes,0, | |||
qBytes,Q_LENGTH - encodedQBytesLength, Q_LENGTH); | |||
} | |||
if (encodedDPBytesLength > DP_LENGTH) { | |||
System.arraycopy(encodedDPBytes,encodedDPBytesLength - DP_LENGTH, | |||
dPBytes,0, DP_LENGTH); | |||
} else { | |||
System.arraycopy(encodedDPBytes,0, | |||
dPBytes,DP_LENGTH - encodedDPBytesLength, DP_LENGTH); | |||
} | |||
byte[] privExpBytes = bigInteger2Bytes(privExp,PRIVEXP_LENGTH); | |||
byte[] pBytes = bigInteger2Bytes(p,P_LENGTH); | |||
byte[] qBytes = bigInteger2Bytes(q,Q_LENGTH); | |||
byte[] dPBytes = bigInteger2Bytes(dP,DP_LENGTH); | |||
byte[] dQBytes = bigInteger2Bytes(dQ,DQ_LENGTH); | |||
byte[] qInvBytes = bigInteger2Bytes(qInv,QINV_LENGTH); | |||
if (encodedDQBytesLength > DQ_LENGTH) { | |||
System.arraycopy(encodedDQBytes,encodedDQBytesLength - DQ_LENGTH, | |||
dQBytes,0, DQ_LENGTH); | |||
} else { | |||
System.arraycopy(encodedDQBytes,0, | |||
dQBytes,DQ_LENGTH - encodedDQBytesLength, DQ_LENGTH); | |||
} | |||
if (encodedQInvBytesLength > QINV_LENGTH) { | |||
System.arraycopy(encodedQInvBytes,encodedQInvBytesLength - QINV_LENGTH, | |||
qInvBytes,0, QINV_LENGTH); | |||
} else { | |||
System.arraycopy(encodedQInvBytes,0, | |||
qInvBytes,QINV_LENGTH - encodedQInvBytesLength, QINV_LENGTH); | |||
} | |||
return BytesUtils.concat(modulusBytes,pubExpBytes,privExpBytes,pBytes,qBytes,dPBytes,dQBytes,qInvBytes); | |||
} | |||
@@ -524,15 +440,14 @@ public class RSAUtils { | |||
try { | |||
keyFactory = KeyFactory.getInstance("RSA"); | |||
} catch (NoSuchAlgorithmException e) { | |||
e.printStackTrace(); | |||
throw new com.jd.blockchain.crypto.CryptoException(e.getMessage(), e); | |||
} | |||
RSAPrivateCrtKeyImpl privateKey = null; | |||
RSAPrivateCrtKeyImpl privateKey; | |||
try { | |||
assert keyFactory != null; | |||
privateKey = (RSAPrivateCrtKeyImpl) keyFactory.generatePrivate(keySpec); | |||
} catch (InvalidKeySpecException e) { | |||
e.printStackTrace(); | |||
throw new com.jd.blockchain.crypto.CryptoException(e.getMessage(), e); | |||
} | |||
assert privateKey != null; | |||
@@ -587,4 +502,21 @@ public class RSAUtils { | |||
return new RSAPrivateCrtKeyParameters(modulus, pubExp, privExp, p, q, dP, dQ, qInv); | |||
} | |||
private static byte[] bigInteger2Bytes(BigInteger src, int length){ | |||
byte[] result = new byte[length]; | |||
byte[] srcBytes = src.toByteArray(); | |||
int srcLength = srcBytes.length; | |||
if (srcLength > length) { | |||
System.arraycopy(srcBytes,srcLength - length, | |||
result,0, length); | |||
} else { | |||
System.arraycopy(srcBytes,0, | |||
result,length - srcLength, length); | |||
} | |||
return result; | |||
} | |||
} |
@@ -7,6 +7,13 @@ import org.bouncycastle.crypto.params.RSAKeyParameters; | |||
import org.bouncycastle.crypto.params.RSAPrivateCrtKeyParameters; | |||
import org.junit.Test; | |||
import javax.crypto.BadPaddingException; | |||
import javax.crypto.Cipher; | |||
import javax.crypto.IllegalBlockSizeException; | |||
import javax.crypto.NoSuchPaddingException; | |||
import java.security.*; | |||
import java.security.interfaces.RSAPrivateKey; | |||
import java.security.interfaces.RSAPublicKey; | |||
import java.util.Random; | |||
import static org.junit.Assert.*; | |||
@@ -131,22 +138,24 @@ public class RSAUtilsTest { | |||
@Test | |||
public void decryptTest(){ | |||
byte[] data = new byte[512]; | |||
Random random = new Random(); | |||
random.nextBytes(data); | |||
AsymmetricCipherKeyPair keyPair = RSAUtils.generateKeyPair(); | |||
AsymmetricKeyParameter pubKey = keyPair.getPublic(); | |||
AsymmetricKeyParameter privKey = keyPair.getPrivate(); | |||
byte[] privKeyBytes = RSAUtils.privKey2Bytes_RawKey((RSAPrivateCrtKeyParameters) privKey); | |||
byte[] ciphertext = RSAUtils.encrypt(data,pubKey); | |||
byte[] data; | |||
for (int i = 1; i < 1024; i++) { | |||
data = new byte[i]; | |||
Random random = new Random(); | |||
random.nextBytes(data); | |||
byte[] ciphertext = RSAUtils.encrypt(data, pubKey); | |||
byte[] plaintextFromPrivKey = RSAUtils.decrypt(ciphertext,privKey); | |||
byte[] plaintextFromPrivKeyBytes = RSAUtils.decrypt(ciphertext,privKeyBytes); | |||
byte[] plaintextFromPrivKey = RSAUtils.decrypt(ciphertext, privKey); | |||
byte[] plaintextFromPrivKeyBytes = RSAUtils.decrypt(ciphertext, privKeyBytes); | |||
assertArrayEquals(data,plaintextFromPrivKey); | |||
assertArrayEquals(data,plaintextFromPrivKeyBytes); | |||
assertArrayEquals(data, plaintextFromPrivKey); | |||
assertArrayEquals(data, plaintextFromPrivKeyBytes); | |||
} | |||
} | |||
@@ -189,4 +198,58 @@ public class RSAUtilsTest { | |||
(count * 1000.00D) / elapsedTS)); | |||
} | |||
} | |||
@Test | |||
public void consistencyTest(){ | |||
byte[] data = new byte[222]; | |||
Random random = new Random(); | |||
random.nextBytes(data); | |||
KeyPairGenerator keyPairGen = null; | |||
try { | |||
keyPairGen = KeyPairGenerator.getInstance("RSA"); | |||
} catch (NoSuchAlgorithmException e) { | |||
e.printStackTrace(); | |||
} | |||
assert keyPairGen != null; | |||
keyPairGen.initialize(2048, new SecureRandom()); | |||
KeyPair keyPair = keyPairGen.generateKeyPair(); | |||
RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate(); | |||
RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic(); | |||
byte[] publicKeyBytes = publicKey.getEncoded(); | |||
byte[] privateKeyBytes = privateKey.getEncoded(); | |||
RSAKeyParameters pubKey = RSAUtils.bytes2PubKey_PKCS8(publicKeyBytes); | |||
RSAPrivateCrtKeyParameters privKey = RSAUtils.bytes2PrivKey_PKCS8(privateKeyBytes); | |||
Cipher cipher; | |||
byte[] ciphertext = null; | |||
try { | |||
cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding"); | |||
cipher.init(Cipher.ENCRYPT_MODE, publicKey); | |||
ciphertext = cipher.doFinal(data); | |||
} catch (NoSuchAlgorithmException | NoSuchPaddingException | InvalidKeyException | |||
| IllegalBlockSizeException | BadPaddingException e) { | |||
e.printStackTrace(); | |||
} | |||
assert ciphertext != null; | |||
byte[] plaintext = RSAUtils.decrypt(ciphertext,privKey); | |||
assertArrayEquals(data,plaintext); | |||
ciphertext = RSAUtils.encrypt(data,pubKey); | |||
try { | |||
cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding"); | |||
cipher.init(Cipher.DECRYPT_MODE, privateKey); | |||
plaintext = cipher.doFinal(ciphertext); | |||
} catch (NoSuchAlgorithmException | NoSuchPaddingException | InvalidKeyException | |||
| IllegalBlockSizeException | BadPaddingException e) { | |||
e.printStackTrace(); | |||
} | |||
assertArrayEquals(data,plaintext); | |||
} | |||
} |