| @@ -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); | |||
| } | |||
| } | |||