AES是非对称加密,有公钥/私钥。
一、创建秘钥对 openssl和jdk都可以生成秘钥对,但要注意的是他们会有默认规范 ,这可能会导致在不同的平台上不通用。推荐在线生成。
1. 在线生成 【在线生成公钥私钥对,RSA公私钥生成】 可以在线生成。
RSA非对称加密公私钥对生成,输出PEM格式的公私钥对,同时支持PKCS#1、PKCS#8密钥格式输出;生成的公私钥对,可拷贝到文本文件,保存为.key文件即可使用。
PEM格式:RSA公私钥对常用的编码方式,OPENSSL以PEM格式为主,相对DER可读性更强,以BASE64编码呈现; 开头类似 —–BEGIN PRIVATE KEY—– 结尾类似 —–END PRIVATE KEY—–
PKCS#8密钥格式,多用于JAVA、PHP程序加解密中,为目前用的比较多的密钥、证书格式; PKCS#1密钥格式,多用于JS等其它程序加解密,属于比较老的格式标准。 PKCS#1和PKCS#8的主要区别,从本质上说,PKCS#8格式增加验证数据段,保证密钥正确性。
2. openssl生成 生成私钥,长度1024(一般会推荐2048)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 $ openssl version OpenSSL 1.1.1f 31 Mar 2020 $ openssl genrsa -out rsa_private_key.pem 1024 Generating RSA private key, 1024 bit long modulus (2 primes) ...............+++++ ...................................................+++++ e is 65537 (0x010001) $ cat rsa_private_key.pem -----BEGIN RSA PRIVATE KEY----- MIICXgIBAAKBgQDMtvNrm4VDreYXzMRnJ4htiBPnnw9djDL5aLQUYm3w2TQ0CGD1 KMBhsm7hC5sf4RkODQYq6Wp1mkL30GStfbaal1S9ILnt9w51P0IpOqAFNZ6jwAtr WUhUhrr+33vcJ8gQh4+fJcAEXvrWbNnTCj9zHFDMelo7bR2PsDLJ6jqqkwIDAQAB AoGBAKFO9AZx2JOY3rsYPhaufwEX/d9AZcIn7C69Q1DgspLbBBiQFZ54iwcwq9Am 7ggzviNlPdvoa1vZvzU4f2x5p71FIGZn6rSb00TB4GxvXox1VOd9bcdj0iDrclDu O/Wt408Pct1TpYA2OwoxFvSgY5wxpZilxHiiRghypFK5sooZAkEA9Zh3Vfq12+fR 8EDHHZKKtJug+jnuSdnoZIjhjB8Ki7Uor/+uQlxjoTW/PwYJKCoIFBhIcBA1h5tl zCQHPgCcBQJBANVjH3IYUGtC834DvIaZQCCa9oG38cbnSF5mqPrhV769hXXsc0XM I2/ZitKCFC0vg/D3lCE52vPi4w142tMbB7cCQQC/nCuG1iqqnivp8PAof1teW4l1 kFr8HVm1jiHCi7lTlIxg++898Qz+CoviJNhiEKDq5KMnY04QNcpvQbCwzBLtAkEA kcAuzmPFKj6EymIK93Td1GeEUH4v6sg3KiO87//TSzlwW2eyJM6WteNFaxvmZCa8 XG7/AuLdpxAmPiF6dg9UaQJAVP+oZrFdqBvutIBlLdg9ZmLXHwk4oqbLexcPI4mB +bc0Qeuv4vV1x6M/024Ae6SCC4ywnx9xNVTedn6siZfNNQ== -----END RSA PRIVATE KEY-----
根据私钥生成公钥
1 2 3 4 5 6 7 8 9 10 $ openssl rsa -in rsa_private_key.pem -out rsa_public_key.pem -pubout writing RSA key $ cat rsa_public_key.pem -----BEGIN PUBLIC KEY----- MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDMtvNrm4VDreYXzMRnJ4htiBPn nw9djDL5aLQUYm3w2TQ0CGD1KMBhsm7hC5sf4RkODQYq6Wp1mkL30GStfbaal1S9 ILnt9w51P0IpOqAFNZ6jwAtrWUhUhrr+33vcJ8gQh4+fJcAEXvrWbNnTCj9zHFDM elo7bR2PsDLJ6jqqkwIDAQAB -----END PUBLIC KEY-----
注意:此时的私钥还不能直接被使用,需要进行PKCS#8编码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 $ pkcs8 -topk8 -in rsa_private_key.pem -out pkcs8_rsa_private_key.pem -nocrypt $ cat pkcs8_rsa_private_key.pem -----BEGIN PRIVATE KEY----- MIICeAIBADANBgkqhkiG9w0BAQEFAASCAmIwggJeAgEAAoGBAMy282ubhUOt5hfM xGcniG2IE+efD12MMvlotBRibfDZNDQIYPUowGGybuELmx/hGQ4NBirpanWaQvfQ ZK19tpqXVL0gue33DnU/Qik6oAU1nqPAC2tZSFSGuv7fe9wnyBCHj58lwARe+tZs 2dMKP3McUMx6WjttHY+wMsnqOqqTAgMBAAECgYEAoU70BnHYk5jeuxg+Fq5/ARf9 30BlwifsLr1DUOCyktsEGJAVnniLBzCr0CbuCDO+I2U92+hrW9m/NTh/bHmnvUUg ZmfqtJvTRMHgbG9ejHVU531tx2PSIOtyUO479a3jTw9y3VOlgDY7CjEW9KBjnDGl mKXEeKJGCHKkUrmyihkCQQD1mHdV+rXb59HwQMcdkoq0m6D6Oe5J2ehkiOGMHwqL tSiv/65CXGOhNb8/BgkoKggUGEhwEDWHm2XMJAc+AJwFAkEA1WMfchhQa0LzfgO8 hplAIJr2gbfxxudIXmao+uFXvr2FdexzRcwjb9mK0oIULS+D8PeUITna8+LjDXja 0xsHtwJBAL+cK4bWKqqeK+nw8Ch/W15biXWQWvwdWbWOIcKLuVOUjGD77z3xDP4K i+Ik2GIQoOrkoydjThA1ym9BsLDMEu0CQQCRwC7OY8UqPoTKYgr3dN3UZ4RQfi/q yDcqI7zv/9NLOXBbZ7Ikzpa140VrG+ZkJrxcbv8C4t2nECY+IXp2D1RpAkBU/6hm sV2oG+60gGUt2D1mYtcfCTiipst7Fw8jiYH5tzRB66/i9XXHoz/TbgB7pIILjLCf H3E1VN52fqyJl801 -----END PRIVATE KEY-----
参考【Java中使用OpenSSL生成的RSA公私钥进行数据加解密】
3. Java代码生成 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance("RSA" );keyPairGen.initialize(1024 ); KeyPair keyPair = keyPairGen.generateKeyPair();RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic();RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate();System.out.println("-----BEGIN PUBLIC KEY-----" ); System.out.println(Base64.getEncoder().encodeToString(publicKey.getEncoded())); System.out.println("-----END PUBLIC KEY-----" ); System.out.println("\n" ); System.out.println("-----BEGIN PRIVATE KEY-----" ); System.out.println(Base64.getEncoder().encodeToString(privateKey.getEncoded())); System.out.println("-----END PRIVATE KEY-----" );
二、加密解密 这里采用的是上面的 “【openssl生成】” 的秘钥对。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 import javax.crypto.Cipher;import java.nio.charset.StandardCharsets;import java.security.KeyFactory;import java.security.PrivateKey;import java.security.PublicKey;import java.security.spec.PKCS8EncodedKeySpec;import java.security.spec.X509EncodedKeySpec;import java.util.Base64;public class TestRsa4 { private static final String PRI_KEY = "MIICeAIBADANBgkqhkiG9w0BAQEFAASCAmIwggJeAgEAAoGBAMy282ubhUOt5hfMxGcniG2IE+efD12MMvlotBRibfDZNDQIYPUowGGybuELmx/hGQ4NBirpanWaQvfQZK19tpqXVL0gue33DnU/Qik6oAU1nqPAC2tZSFSGuv7fe9wnyBCHj58lwARe+tZs2dMKP3McUMx6WjttHY+wMsnqOqqTAgMBAAECgYEAoU70BnHYk5jeuxg+Fq5/ARf930BlwifsLr1DUOCyktsEGJAVnniLBzCr0CbuCDO+I2U92+hrW9m/NTh/bHmnvUUgZmfqtJvTRMHgbG9ejHVU531tx2PSIOtyUO479a3jTw9y3VOlgDY7CjEW9KBjnDGlmKXEeKJGCHKkUrmyihkCQQD1mHdV+rXb59HwQMcdkoq0m6D6Oe5J2ehkiOGMHwqLtSiv/65CXGOhNb8/BgkoKggUGEhwEDWHm2XMJAc+AJwFAkEA1WMfchhQa0LzfgO8hplAIJr2gbfxxudIXmao+uFXvr2FdexzRcwjb9mK0oIULS+D8PeUITna8+LjDXja0xsHtwJBAL+cK4bWKqqeK+nw8Ch/W15biXWQWvwdWbWOIcKLuVOUjGD77z3xDP4Ki+Ik2GIQoOrkoydjThA1ym9BsLDMEu0CQQCRwC7OY8UqPoTKYgr3dN3UZ4RQfi/qyDcqI7zv/9NLOXBbZ7Ikzpa140VrG+ZkJrxcbv8C4t2nECY+IXp2D1RpAkBU/6hmsV2oG+60gGUt2D1mYtcfCTiipst7Fw8jiYH5tzRB66/i9XXHoz/TbgB7pIILjLCfH3E1VN52fqyJl801" ; private static final String PUB_KEY = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDMtvNrm4VDreYXzMRnJ4htiBPnnw9djDL5aLQUYm3w2TQ0CGD1KMBhsm7hC5sf4RkODQYq6Wp1mkL30GStfbaal1S9ILnt9w51P0IpOqAFNZ6jwAtrWUhUhrr+33vcJ8gQh4+fJcAEXvrWbNnTCj9zHFDMelo7bR2PsDLJ6jqqkwIDAQAB" ; public static void main (String[] args) throws Exception { String encr = encrypted("1212121212" , PUB_KEY); String result = decrypt(encr, PRI_KEY); System.out.println(result); } public static String encrypted (String content,String pubkey) throws Exception { KeyFactory keyFactory = KeyFactory.getInstance("RSA" ); X509EncodedKeySpec keySpec = new X509EncodedKeySpec (Base64.getDecoder().decode(pubkey)); PublicKey publicKey = keyFactory.generatePublic(keySpec); Cipher cipher = Cipher.getInstance("RSA" ); cipher.init(Cipher.ENCRYPT_MODE, publicKey); return Base64.getEncoder().encodeToString(cipher.doFinal(content.getBytes(StandardCharsets.UTF_8))); } public static String decrypt (String cryptograph, String prikey) throws Exception { PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec (Base64.getDecoder().decode(prikey)); PrivateKey privateKey = KeyFactory.getInstance("RSA" ).generatePrivate(keySpec); Cipher cipher = Cipher.getInstance("RSA" ); cipher.init(Cipher.DECRYPT_MODE, privateKey); byte [] b = Base64.getDecoder().decode(cryptograph); return new String (cipher.doFinal(b)); } }