参考椭圆曲线加密:elliptic curve cryptography (ECC), 这里的椭圆曲线:elliptic curve(EC)。
使用公钥加密,再使用私钥解密。不像RSA,既可以使用公钥加密,再使用私钥解密,也可以私钥加密,再使用公钥解密
private static Provider provider = null; private static BCECPrivateKey privateKey = null; private static byte[] privateKeyEncoded1 = null; private static BCECPublicKey publicKey = null; private static byte[] publicKeyEncoded1 = null;
@BeforeClass public static void init() /* throws NoSuchAlgorithmException */ { init0(); }
public static void init0() /* throws NoSuchAlgorithmException */ { provider = new BouncyCastleProvider(); // provider = new BouncyCastlePQCProvider(); KeyPairGenerator keyPairGenerator = null; try { keyPairGenerator = KeyPairGenerator.getInstance("EC", provider); // sun.security.rsa.RSAKeyPairGenerator } catch (NoSuchAlgorithmException e) { Assert.fail("no such algorithm: " + e.getMessage()); } keyPairGenerator.initialize(256, new SecureRandom()); KeyPair keyPair1 = keyPairGenerator.generateKeyPair(); privateKey = (BCECPrivateKey) keyPair1.getPrivate(); publicKey = (BCECPublicKey) keyPair1.getPublic(); privateKeyEncoded1 = privateKey.getEncoded(); publicKeyEncoded1 = publicKey.getEncoded(); System.out.println("private key: " + Base64.byteArrayToBase64(privateKeyEncoded1)); System.out.println("public key: " + Base64.byteArrayToBase64(publicKeyEncoded1)); }
/** * 使用公钥加密,再使用私钥解密 */ @Test public void test1() { String message = "13120983870"; System.out.println(message); IESCipher.ECIESwithAES cipher1 = new IESCipher.ECIESwithAES(); try { cipher1.engineInit(Cipher.ENCRYPT_MODE, publicKey, new SecureRandom()); } catch (InvalidKeyException e) { Assert.fail("invalid key: " + e.getMessage()); } byte[] encryption1 = null; try { encryption1 = cipher1.engineDoFinal(message.getBytes(), 0, message.getBytes().length); } catch (IllegalBlockSizeException e) { Assert.fail("illegal block size: " + e.getMessage()); } catch (BadPaddingException e) { Assert.fail("bad padding: " + e.getMessage()); } System.out.println("encryption: " + Base64.byteArrayToBase64(encryption1)); cipher1 = new IESCipher.ECIESwithAES(); try { cipher1.engineInit(Cipher.DECRYPT_MODE, privateKey, new SecureRandom()); } catch (InvalidKeyException e) { Assert.fail("invalid key: " + e.getMessage()); } byte[] decryption1 = null; try { decryption1 = cipher1.engineDoFinal(encryption1, 0, encryption1.length); } catch (IllegalBlockSizeException e) { Assert.fail("illegal block size: " + e.getMessage()); } catch (BadPaddingException e) { Assert.fail("bad padding: " + e.getMessage()); } System.out.println("decryption: " + new String(decryption1) + ", base64:" + Base64.byteArrayToBase64(decryption1)); }
private key: MIGTAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBHkwdwIBAQQgQ4vAWWNYMncNYX/kkgxPhUullJk4UR5hTEW1krcqD32gCgYIKoZIzj0DAQehRANCAATs04Bcawzubw4ozfPRhkZpykWw6TErFPhIwOYihY/RrbaiaIGJJdvbIpxm3D+YqFcnSSbTH5WXrxpQToXiUPtc public key: MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE7NOAXGsM7m8OKM3z0YZGacpFsOkxKxT4SMDmIoWP0a22omiBiSXb2yKcZtw/mKhXJ0km0x+Vl68aUE6F4lD7XA== 13120983870 encryption: BK8kO9AQoMYqTK8/BedPndCfVPpxhuvfSxUHM0UDNeWNV6RsaDOI0/XTC/5BGIkbt40JN7/T8wY9NfDZYx/jye5w09aqt90TIzBpBL7MC1jgBieji433pu2ZzhSizVwJ9QCt0zc= decryption: 13120983870, base64:MTMxMjA5ODM4NzA=
private void encryptAndDecrypt(String message, PrivateKey privateKey, PublicKey publicKey) { IESCipher.ECIESwithAES cipher1 = new IESCipher.ECIESwithAES(); try { cipher1.engineInit(Cipher.ENCRYPT_MODE, publicKey, new SecureRandom()); } catch (InvalidKeyException e) { Assert.fail("invalid key: " + e.getMessage()); } byte[] encryption1 = null; try { encryption1 = cipher1.engineDoFinal(message.getBytes(), 0, message.getBytes().length); } catch (IllegalBlockSizeException e) { Assert.fail("illegal block size: " + e.getMessage()); } catch (BadPaddingException e) { Assert.fail("bad padding: " + e.getMessage()); } System.out.println("encryption: " + Base64.byteArrayToBase64(encryption1)); cipher1 = new IESCipher.ECIESwithAES(); try { cipher1.engineInit(Cipher.DECRYPT_MODE, privateKey, new SecureRandom()); } catch (InvalidKeyException e) { Assert.fail("invalid key: " + e.getMessage()); } byte[] decryption1 = null; try { decryption1 = cipher1.engineDoFinal(encryption1, 0, encryption1.length); } catch (IllegalBlockSizeException e) { Assert.fail("illegal block size: " + e.getMessage()); } catch (BadPaddingException e) { Assert.fail("bad padding: " + e.getMessage()); } System.out.println("decryption: " + new String(decryption1) + ", base64:" + Base64.byteArrayToBase64(decryption1)); }
@Test public void test_1() { String privKey = "MIGTAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBHkwdwIBAQQg9ye6MPlsZbIKD3hwqWebMOkmcKHlk0NEmTbPKQDZxe2gCgYIKoZIzj0DAQehRANCAARZXl/Wn+3uVSyk/VDncYFNazAjPMEBXEwS/iWy0hwidaU3t3OrYXVMsE5xqx7qtgmBu0/dbCdyUmwMVL5CclFq"; String pubKey = "MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEWV5f1p/t7lUspP1Q53GBTWswIzzBAVxMEv4lstIcInWlN7dzq2F1TLBOcase6rYJgbtP3WwnclJsDFS+QnJRag=="; byte[] privateKeyEncoded = Base64.base64ToByteArray(privKey); byte[] publicKeyEncoded = Base64.base64ToByteArray(pubKey); String message = "13120983870"; System.out.println(message); PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(privateKeyEncoded); ECKeyFactorySpi keyFactory = new ECKeyFactorySpi(); PrivateKey privateKey = null; try { privateKey = keyFactory.engineGeneratePrivate(pkcs8KeySpec); } catch (InvalidKeySpecException e) { Assert.fail("invalid key spec: " + e.getMessage()); } System.out.println("private key: " + Base64.byteArrayToBase64(((Key) privateKey).getEncoded())); X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(publicKeyEncoded); keyFactory = new ECKeyFactorySpi(); PublicKey publicKey = null; try { publicKey = keyFactory.engineGeneratePublic(x509KeySpec); } catch (InvalidKeySpecException e) { Assert.fail("invalid key spec: " + e.getMessage()); } System.out.println("public key: " + Base64.byteArrayToBase64(((Key) publicKey).getEncoded())); encryptAndDecrypt(message, privateKey, publicKey); }
13120983870 private key: MIGTAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBHkwdwIBAQQg9ye6MPlsZbIKD3hwqWebMOkmcKHlk0NEmTbPKQDZxe2gCgYIKoZIzj0DAQehRANCAARZXl/Wn+3uVSyk/VDncYFNazAjPMEBXEwS/iWy0hwidaU3t3OrYXVMsE5xqx7qtgmBu0/dbCdyUmwMVL5CclFq public key: MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEWV5f1p/t7lUspP1Q53GBTWswIzzBAVxMEv4lstIcInWlN7dzq2F1TLBOcase6rYJgbtP3WwnclJsDFS+QnJRag== encryption: BLcrguLmGY9Hetf7UmtAyTg+8fVmH2Ya/oBjRHzwkbTZpiKbOBR+a44y2PJROBZDFBDZJTExb17HqRe1XFxeDSA5mmb2t1xhwxwd4PgckThbGhLewx151Mww2eyA9gWDMC9Wqrs= decryption: 13120983870, base64:MTMxMjA5ODM4NzA=
package org.spongycastle.jcajce.provider.asymmetric.ec; import java.security.PrivateKey; import java.security.PublicKey; import java.security.spec.InvalidKeySpecException; import java.security.spec.KeySpec; import org.spongycastle.jce.provider.BouncyCastleProvider; public class ECKeyFactorySpi extends org.spongycastle.jcajce.provider.asymmetric.ec.KeyFactorySpi { public ECKeyFactorySpi() { super("EC", BouncyCastleProvider.CONFIGURATION); } public PrivateKey engineGeneratePrivate( KeySpec keySpec) throws InvalidKeySpecException { return super.engineGeneratePrivate(keySpec); } public PublicKey engineGeneratePublic( KeySpec keySpec) throws InvalidKeySpecException { return super.engineGeneratePublic(keySpec); } }