PKI - 非对称加密算法

2024-04-25 18:38
文章标签 加密算法 非对称 pki

本文主要是介绍PKI - 非对称加密算法,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

非对称加密算法

  • 1. 密钥交换算法(DH&ECDH)
    • 1.1 DH
    • 1.2 ECDH
  • 2. 典型非对称加密算法 - RSA
  • 3. 常用非对称加密算法 - ElGamal

密钥管理是对称加密算法系统不容忽视的问题,它成为安全系统中最为薄弱的环节。为了弥补这一弱势,非对称加密算法应运而生。

非对称加密算法源于DH算法(Diffie-Hellman,密钥交换算法),由W.Diffie和M.Hellman共同提出。该算法为非对称加密算法奠定了基础,堪称非对称加密算法之鼻祖。

DH算法提出后,国际上相继出现了各种实用性更强的非对称加密算法,其构成主要是基于数学问题的求解,主要分为两类:

  • 基于因子分解难题。RSA算法是最为典型的非对称加密算法,该算法由美国麻省理工学院(MIT)的Ron Rivest、Adi Shamir和Leonard Adleman三位学者提出,并以这三位学者的姓氏开头字母命名,称为RSA算法。RSA算法是当今应用范围最为广泛的非对称加密算法,也是第一个既能用于数据加密也能用于数字签名的算法。

  • 基于离散对数难题。ElGamal算法由TaherElGamal提出,以自己的名字命名。该算法既可用于加密/解密,也可用于数字签名,并为数字签名算法形成标准提供参考。美国的DSS(Digital Signature Standard,数据签名标准)的DSA(Digital Signature Algorithm,数字签名算法)经ElGamal算法演变而来。

ECC(Elliptical Curve Cryptography,椭圆曲线加密)算法以椭圆曲线理论为基础,在创建密钥时可做到更快、更小,并且更有效。ECC算法通过椭圆曲线方程式的性质产生密钥,而不是采用传统的方法利用大质数的积来产生。

1. 密钥交换算法(DH&ECDH)

1.1 DH

对称加密算法提高数据安全性的同时带来了密钥管理的复杂性。消息收发双方若想发送加密消息,必须事先约定好加密算法并发放密钥。而如何安全的传递密钥,成为对称加密算法的一个棘手问题。密钥交换算法(Diffie-Hellman算法,简称DH算法)成为解决这一问题的金钥匙!

(甲方)发送方 (乙方)接收方 1. 构建甲方密钥 2. 公布甲方公钥 3. 利用甲方公钥构建乙方密钥 4. 公布乙方公钥 5. 使用甲方私钥、乙方公钥构建本地密钥 6. 使用乙方私钥、甲方公钥构建本地密钥 7. 使用本地密钥对消息加密 8. 发送加密消息 9. 使用本地密钥对消息解密 (甲方)发送方 (乙方)接收方

代码实现

public static final String KEY_ALGORITHM = "DH";
public static final String SECRET_ALGORITHM = "AES";
public static final int KEY_SIZE = 512;
public static final String PUBLIC_KEY = "DHPublicKey";
public static final String PRIVATE_KEY = "DHPrivateKey";/*** 生成甲方密钥对(含公钥、私钥)** @return map* @throws Exception 异常*/
public Map<String, Object> initKey() throws Exception {// 初始化密钥对生成器final KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance(KEY_ALGORITHM);keyPairGenerator.initialize(KEY_SIZE);// 生成密钥对final KeyPair keyPair = keyPairGenerator.generateKeyPair();// 获取公钥final PublicKey publicKey = keyPair.getPublic();// 获取私钥final PrivateKey privateKey = keyPair.getPrivate();// 构造返回mapMap<String, Object> keyMap = new HashMap<>();keyMap.put(PUBLIC_KEY, publicKey);keyMap.put(PRIVATE_KEY, privateKey);return keyMap;
}
/*** 根据甲方公钥生成乙方密钥对(含公钥、私钥)** @param key 甲方公钥* @return map* @throws Exception 异常*/
public Map<String, Object> initKey(byte[] key) throws Exception {// 解析甲方公钥final X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(key);// 实例化密钥工厂final KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);// 产生甲方公钥final PublicKey aPublicKey = keyFactory.generatePublic(x509EncodedKeySpec);// 由甲方公钥构建乙方密钥final DHParameterSpec dhParameterSpec = ((DHPublicKey) aPublicKey).getParams();// 初始化密钥对生成器final KeyPairGenerator dh = KeyPairGenerator.getInstance(keyFactory.getAlgorithm());dh.initialize(dhParameterSpec);// 生成密钥对final KeyPair keyPair = dh.generateKeyPair();// 获取公钥final PublicKey publicKey = keyPair.getPublic();// 获取私钥final PrivateKey privateKey = keyPair.getPrivate();// 构造返回mapMap<String, Object> keyMap = new HashMap<>();keyMap.put(PUBLIC_KEY, publicKey);keyMap.put(PRIVATE_KEY, privateKey);return keyMap;
}
/*** 生成密钥* @param publicKey 对方公钥* @param privateKey 自己私钥* @return 密钥* @throws Exception 异常*/
public byte[] getSecretKey(byte[] publicKey, byte[] privateKey) throws Exception {// 初始化密钥工厂final KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);// 初始化公钥final X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(publicKey);final PublicKey pubKey = keyFactory.generatePublic(x509EncodedKeySpec);// 初始化私钥final PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(privateKey);final PrivateKey priKey = keyFactory.generatePrivate(pkcs8EncodedKeySpec);// 实例化final KeyAgreement keyAgreement = KeyAgreement.getInstance(keyFactory.getAlgorithm());keyAgreement.init(priKey);keyAgreement.doPhase(pubKey, true);// 生成本地密钥final SecretKey secretKey = keyAgreement.generateSecret(SECRET_ALGORITHM);return secretKey.getEncoded();
}
/*** 取得公钥** @param keyMap 密钥map* @return 公钥*/
public byte[] getPublicKey(Map<String, Object> keyMap) {final Key key = (Key) keyMap.get(PUBLIC_KEY);return key.getEncoded();
}/*** 取得私钥** @param keyMap 密钥map* @return 私钥*/
public byte[] getPrivateKey(Map<String, Object> keyMap) {final Key key = (Key) keyMap.get(PRIVATE_KEY);return key.getEncoded();
}
/*** 数据加密** @param data 待加密数据* @param key  密钥* @return 加密后数据*/
public byte[] encrypt(byte[] data, byte[] key) throws Exception {// 生成本地密钥final SecretKeySpec secretKeySpec = new SecretKeySpec(key, SECRET_ALGORITHM);// 数据加密final Cipher cipher = Cipher.getInstance(secretKeySpec.getAlgorithm());cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec);return cipher.doFinal(data);
}/*** 数据解密** @param data 待解密数据* @param key  密钥* @return 解密后数据*/
public byte[] decrypt(byte[] data, byte[] key) throws Exception {// 生成本地密钥final SecretKeySpec secretKeySpec = new SecretKeySpec(key, SECRET_ALGORITHM);// 数据加密final Cipher cipher = Cipher.getInstance(secretKeySpec.getAlgorithm());cipher.init(Cipher.DECRYPT_MODE, secretKeySpec);return cipher.doFinal(data);
}

测试用例

@Test
public void testDH() throws Exception {final Map<String, Object> aKeyMap = initKey();final byte[] aPublicKey = getPublicKey(aKeyMap);final byte[] aPrivateKey = getPrivateKey(aKeyMap);System.out.println("甲方公钥:" + Base64.toBase64String(aPublicKey));System.out.println("甲方私钥:" + Base64.toBase64String(aPrivateKey));final Map<String, Object> bKeyMap = initKey(aPublicKey);final byte[] bPublicKey = getPublicKey(bKeyMap);final byte[] bPrivateKey = getPrivateKey(bKeyMap);System.out.println("乙方公钥:" + Base64.toBase64String(bPublicKey));System.out.println("乙方私钥:" + Base64.toBase64String(bPrivateKey));final byte[] aSecretKey = getSecretKey(bPublicKey, aPrivateKey);final byte[] bSecretKey = getSecretKey(aPublicKey, bPrivateKey);System.out.println("甲方密钥:" + Base64.toBase64String(aSecretKey));System.out.println("乙方密钥:" + Base64.toBase64String(bSecretKey));final byte[] aEncrypt = encrypt("我是阿汤哥".getBytes(), aSecretKey);final byte[] bDecrypt = decrypt(aEncrypt, bSecretKey);System.out.println("甲方加密消息:" + Base64.toBase64String(aEncrypt));System.out.println("乙方解密消息:" + Base64.toBase64String(bDecrypt));final byte[] bEncrypt = encrypt("Hello, 阿汤哥".getBytes(), bSecretKey);final byte[] aDecrypt = decrypt(bEncrypt, aSecretKey);System.out.println("乙方加密消息:" + Base64.toBase64String(bEncrypt));System.out.println("甲方解密消息:" + Base64.toBase64String(aDecrypt));
}

使用jdk8执行本用例时如果报错

java.security.NoSuchAlgorithmException: Unsupported secret key algorithm: AESat com.sun.crypto.provider.DHKeyAgreement.engineGenerateSecret(DHKeyAgreement.java:387)at javax.crypto.KeyAgreement.generateSecret(KeyAgreement.java:648)at com.jd.eps.eis.product.core.config.DHTest.getSecretKey(DHTest.java:110)at com.jd.eps.eis.product.core.config.DHTest.testDH(DHTest.java:183)

可以通过增加vm参数 -Djdk.crypto.KeyAgreement.legacyKDF=true 解决。

执行结果

甲方公钥:MIHgMIGXBgkqhkiG9w0BAwEwgYkCQQD8poLOjhLKuibvzPcRDlJtsHiwXt7LzR60ogjzrhYXrgHzW5Gkfm32NBPF4S7QiZvNEyrNUNmRUb3EPuc3WS4XAkBnhHGyepz0TukaScUUfbGpqvJE8FpDTWSGkx0tFCcbnjUDC3H9c9oXkGmzLik1Yw4cIGI1TQ2iCmxBblC+eUykAgIBgANEAAJBAMCeFF4M4gFXNabyak7DplZnTVPJCNpw9eOao4BWNrdu8ptUiTg4kwmP8bxjot873vQ7QDg4cPyTFJGZ/c3HApE=
甲方私钥:MIHSAgEAMIGXBgkqhkiG9w0BAwEwgYkCQQD8poLOjhLKuibvzPcRDlJtsHiwXt7LzR60ogjzrhYXrgHzW5Gkfm32NBPF4S7QiZvNEyrNUNmRUb3EPuc3WS4XAkBnhHGyepz0TukaScUUfbGpqvJE8FpDTWSGkx0tFCcbnjUDC3H9c9oXkGmzLik1Yw4cIGI1TQ2iCmxBblC+eUykAgIBgAQzAjEA1f2vYbDfzWpVlX8ib4ftWD5q24Mzh74C0L+ze8ienkfwv41dErOl0HqZOmmf18HN
乙方公钥:MIHgMIGXBgkqhkiG9w0BAwEwgYkCQQD8poLOjhLKuibvzPcRDlJtsHiwXt7LzR60ogjzrhYXrgHzW5Gkfm32NBPF4S7QiZvNEyrNUNmRUb3EPuc3WS4XAkBnhHGyepz0TukaScUUfbGpqvJE8FpDTWSGkx0tFCcbnjUDC3H9c9oXkGmzLik1Yw4cIGI1TQ2iCmxBblC+eUykAgIBgANEAAJBAJ3BzkiX8n6RurBasjqLYwCbewwX0ZkWykCzyQj6y/4uBgNX0m+0bgPX1emxlFt/N3ueC8803OhNcprcHRxschY=
乙方私钥:MIHSAgEAMIGXBgkqhkiG9w0BAwEwgYkCQQD8poLOjhLKuibvzPcRDlJtsHiwXt7LzR60ogjzrhYXrgHzW5Gkfm32NBPF4S7QiZvNEyrNUNmRUb3EPuc3WS4XAkBnhHGyepz0TukaScUUfbGpqvJE8FpDTWSGkx0tFCcbnjUDC3H9c9oXkGmzLik1Yw4cIGI1TQ2iCmxBblC+eUykAgIBgAQzAjEAqi55vmMEF5pfS4//fvfqELLlo817cCRlRMOZ+sQ9HLtroIJ16x7RWusDpK75dqxA
甲方密钥:sSVOKIBcVtQ5h806csVXzmkPZWUhC75Xp9glwAjFWhY=
乙方密钥:sSVOKIBcVtQ5h806csVXzmkPZWUhC75Xp9glwAjFWhY=
甲方加密消息:DPftIVbpAGj7dkF73QB4zw==
乙方解密消息:我是阿汤哥
乙方加密消息:FTZnyPN+ZAzdqU4vEKjkMCo6U0TLlKPDyL3zoBSGvvQ=
甲方解密消息:Hello, 阿汤哥

1.2 ECDH

JDK8没有ECDH的实现,需要添加Provider。

Security.addProvider(new BouncyCastleProvider());

根据甲方公钥生成乙方密钥对时需对ParameterSpec进行调整。

/*** 根据甲方公钥生成乙方密钥对(含公钥、私钥)** @param key 甲方公钥* @return map* @throws Exception 异常*/
public Map<String, Object> initKey(byte[] key) throws Exception {// 解析甲方公钥final X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(key);// 实例化密钥工厂final KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);// 产生甲方公钥final PublicKey aPublicKey = keyFactory.generatePublic(x509EncodedKeySpec);// 由甲方公钥构建乙方密钥final ECParameterSpec ecParameterSpec = ((ECPublicKey) aPublicKey).getParams();// 初始化密钥对生成器final KeyPairGenerator dh = KeyPairGenerator.getInstance(keyFactory.getAlgorithm());dh.initialize(ecParameterSpec);// 生成密钥对final KeyPair keyPair = dh.generateKeyPair();// 获取公钥final PublicKey publicKey = keyPair.getPublic();// 获取私钥final PrivateKey privateKey = keyPair.getPrivate();// 构造返回mapMap<String, Object> keyMap = new HashMap<>();keyMap.put(PUBLIC_KEY, publicKey);keyMap.put(PRIVATE_KEY, privateKey);return keyMap;
}

2. 典型非对称加密算法 - RSA

甲方(发送者) 乙方(接收者) 1. 构建密钥对 2. 发布公钥 3. 使用私钥加密数据 4. 发送加密数据 5. 使用甲方公钥解密数据 6. 使用甲方公钥加密数据 7. 发送加密数据 8. 使用私钥解密数据 甲方(发送者) 乙方(接收者)

代码实现

public static final String KEY_ALGORITHM = "RSA";
public static final int KEY_SIZE = 512;
public static final String PUBLIC_KEY = "DHPublicKey";
public static final String PRIVATE_KEY = "DHPrivateKey";/*** 生成甲方密钥对(含公钥、私钥)** @return map* @throws Exception 异常*/
public Map<String, Object> initKey() throws Exception {// 初始化密钥对生成器final KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance(KEY_ALGORITHM);keyPairGenerator.initialize(KEY_SIZE);// 生成密钥对final KeyPair keyPair = keyPairGenerator.generateKeyPair();// 获取公钥final PublicKey publicKey = keyPair.getPublic();// 获取私钥final PrivateKey privateKey = keyPair.getPrivate();// 构造返回mapMap<String, Object> keyMap = new HashMap<>();keyMap.put(PUBLIC_KEY, publicKey);keyMap.put(PRIVATE_KEY, privateKey);return keyMap;
}/*** 取得公钥** @param keyMap 密钥map* @return 公钥*/
public byte[] getPublicKey(Map<String, Object> keyMap) {final Key key = (Key) keyMap.get(PUBLIC_KEY);return key.getEncoded();
}/*** 取得私钥** @param keyMap 密钥map* @return 私钥*/
public byte[] getPrivateKey(Map<String, Object> keyMap) {final Key key = (Key) keyMap.get(PRIVATE_KEY);return key.getEncoded();
}
/*** 使用私钥加密数据** @param data       待加密数据* @param privateKey 私钥* @return 加密后数据*/
public byte[] encryptByPrivateKey(byte[] data, byte[] privateKey) throws Exception {// 获取私钥final PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(privateKey);final KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);// 生成私钥final PrivateKey priKey = keyFactory.generatePrivate(pkcs8EncodedKeySpec);// 数据加密final Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());cipher.init(Cipher.ENCRYPT_MODE, priKey);return cipher.doFinal(data);
}/*** 使用公钥解密数据** @param data      待解密数据* @param publicKey 公钥* @return 解密后数据*/
public byte[] decryptByPublicKey(byte[] data, byte[] publicKey) throws Exception {// 获取公钥final X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(publicKey);final KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);// 生成公钥final PublicKey pubKey = keyFactory.generatePublic(x509EncodedKeySpec);// 数据加密final Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());cipher.init(Cipher.DECRYPT_MODE, pubKey);return cipher.doFinal(data);
}
/*** 使用公钥加密数据** @param data      待解密数据* @param publicKey 公钥* @return 解密后数据*/
public byte[] encryptByPublicKey(byte[] data, byte[] publicKey) throws Exception {// 获取公钥final X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(publicKey);final KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);// 生成公钥final PublicKey pubKey = keyFactory.generatePublic(x509EncodedKeySpec);// 数据加密final Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());cipher.init(Cipher.ENCRYPT_MODE, pubKey);return cipher.doFinal(data);
}/*** 使用私钥解密数据** @param data       待加密数据* @param privateKey 私钥* @return 加密后数据*/
public byte[] decryptByPrivateKey(byte[] data, byte[] privateKey) throws Exception {// 获取私钥final PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(privateKey);final KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);// 生成私钥final PrivateKey priKey = keyFactory.generatePrivate(pkcs8EncodedKeySpec);// 数据加密final Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());cipher.init(Cipher.DECRYPT_MODE, priKey);return cipher.doFinal(data);
}
@Test
public void testRSA() throws Exception {Security.addProvider(new BouncyCastleProvider());final Map<String, Object> aKeyMap = initKey();final byte[] aPublicKey = getPublicKey(aKeyMap);final byte[] aPrivateKey = getPrivateKey(aKeyMap);System.out.println("甲方公钥:" + Base64.toBase64String(aPublicKey));System.out.println("甲方私钥:" + Base64.toBase64String(aPrivateKey));final byte[] aEncrypt = encryptByPrivateKey("我是阿汤哥".getBytes(), aPrivateKey);final byte[] bDecrypt = decryptByPublicKey(aEncrypt, aPublicKey);System.out.println("甲方:使用甲方私钥加密消息:" + Base64.toBase64String(aEncrypt));System.out.println("乙方:使用甲方公钥解密消息:" + new String(bDecrypt));final byte[] bEncrypt = encryptByPublicKey("Hello, 阿汤哥".getBytes(), aPublicKey);final byte[] aDecrypt = decryptByPrivateKey(bEncrypt, aPrivateKey);System.out.println("乙方:使用甲方公钥加密消息:" + Base64.toBase64String(bEncrypt));System.out.println("甲方:使用甲方私钥解密消息:" + new String(aDecrypt));
}

执行结果

甲方公钥:MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAJ7vEoMQFnSZq8tIKydTxeZQZbg3EzZ+uoqMB6xYUz0bJKTLBE2VdT8SKmhCFjyBLzRla8bCl5EtLB/S3F/isD0CAwEAAQ==
甲方私钥:MIIBUwIBADANBgkqhkiG9w0BAQEFAASCAT0wggE5AgEAAkEAnu8SgxAWdJmry0grJ1PF5lBluDcTNn66iowHrFhTPRskpMsETZV1PxIqaEIWPIEvNGVrxsKXkS0sH9LcX+KwPQIDAQABAkAePbMyCP+c1BiiJ2s+omwHdMjGEoSvW9G2xwo2ut+rwo+UiKX/OXtjggNL32sOG/VBpmwQnCzhHXlM3Uf/AyLBAiEA0j02vlbqrkb4eLLTX/K1ZXk05xFMaxjCfqIdv9VwqykCIQDBhxD/jP48lN/I/cNQjg4710e46gL5U3TvDfmpXZYS9QIgYAHkRfebJAr03OmM7XwAql43cm3L3/xmlT2jKD9oPEECIBAgRh1VTVYU/bTM2Hqc67i2zqYs8cR+3M6StowTXU8FAiAp+LnIyULp1obJN9ZnLRv5RldROa9Evj94cfDq3gu+QQ==
甲方:使用甲方私钥加密消息:lK3A3bNyxV1xc34st8fOtIy5vyjTL1zm7wbU9v5mV21t0hxf1ZLTdvN5+vZPSylF3th0c0KqSdGNLpaazvEYSg==
乙方:使用甲方公钥解密消息:我是阿汤哥
乙方:使用甲方公钥加密消息:msiUhALltZYWQdpDWpp6X4wmDCR3ZVGw4d3AqYBnnwDloNDBivpBhT4LgWseX7x74GpgKFA1g/mpsKCIoXqOiw==
甲方:使用甲方私钥解密消息:Hello, 阿汤哥

3. 常用非对称加密算法 - ElGamal

甲方(发送者) 乙方(接收者) 1. 构建密钥对 2. 发布公钥 3. 使用乙方公钥加密数据 4. 发送加密数据 5. 使用私钥解密数据 甲方(发送者) 乙方(接收者)

代码实现

public static final String KEY_ALGORITHM = "ElGamal";
public static final int KEY_SIZE = 256;
public static final String PUBLIC_KEY = "ElGamalPublicKey";
public static final String PRIVATE_KEY = "ElGamalPrivateKey";/*** 生成甲方密钥对(含公钥、私钥)** @return map* @throws Exception 异常*/
public Map<String, Object> initKey() throws Exception {// 加入BouncyCastleProvider支持Security.addProvider(new BouncyCastleProvider());// 实例化算法参数生成器final AlgorithmParameterGenerator apg = AlgorithmParameterGenerator.getInstance(KEY_ALGORITHM);// 初始化算法生成器apg.init(KEY_SIZE);// 生成算法参数final AlgorithmParameters parameters = apg.generateParameters();// 构建参数材料final DHParameterSpec dhParameterSpec = parameters.getParameterSpec(DHParameterSpec.class);// 实例化密钥对生成器final KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance(KEY_ALGORITHM);keyPairGenerator.initialize(dhParameterSpec, new SecureRandom());// 生成密钥对final KeyPair keyPair = keyPairGenerator.generateKeyPair();// 获取公钥final PublicKey publicKey = keyPair.getPublic();// 获取私钥final PrivateKey privateKey = keyPair.getPrivate();// 构造返回mapMap<String, Object> keyMap = new HashMap<>();keyMap.put(PUBLIC_KEY, publicKey);keyMap.put(PRIVATE_KEY, privateKey);return keyMap;
}/*** 取得公钥** @param keyMap 密钥map* @return 公钥*/
public byte[] getPublicKey(Map<String, Object> keyMap) {final Key key = (Key) keyMap.get(PUBLIC_KEY);return key.getEncoded();
}/*** 取得私钥** @param keyMap 密钥map* @return 私钥*/
public byte[] getPrivateKey(Map<String, Object> keyMap) {final Key key = (Key) keyMap.get(PRIVATE_KEY);return key.getEncoded();
}
/*** 使用公钥加密数据** @param data      待解密数据* @param publicKey 公钥* @return 解密后数据*/
public byte[] encryptByPublicKey(byte[] data, byte[] publicKey) throws Exception {Security.addProvider(new BouncyCastleProvider());// 获取公钥final X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(publicKey);final KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);// 生成公钥final PublicKey pubKey = keyFactory.generatePublic(x509EncodedKeySpec);// 数据加密final Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());cipher.init(Cipher.ENCRYPT_MODE, pubKey);return cipher.doFinal(data);
}/*** 使用私钥解密数据** @param data       待加密数据* @param privateKey 私钥* @return 加密后数据*/
public byte[] decryptByPrivateKey(byte[] data, byte[] privateKey) throws Exception {Security.addProvider(new BouncyCastleProvider());// 获取私钥final PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(privateKey);final KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);// 生成私钥final PrivateKey priKey = keyFactory.generatePrivate(pkcs8EncodedKeySpec);// 数据加密final Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());cipher.init(Cipher.DECRYPT_MODE, priKey);return cipher.doFinal(data);
}
@Test
public void testRSA() throws Exception {Security.addProvider(new BouncyCastleProvider());final Map<String, Object> bKeyMap = initKey();final byte[] bPublicKey = getPublicKey(bKeyMap);final byte[] bPrivateKey = getPrivateKey(bKeyMap);System.out.println("乙方公钥:" + Base64.toBase64String(bPublicKey));System.out.println("乙方私钥:" + Base64.toBase64String(bPrivateKey));final byte[] aEncrypt = encryptByPublicKey("我是阿汤哥".getBytes(), bPublicKey);final byte[] bDecrypt = decryptByPrivateKey(aEncrypt, bPrivateKey);System.out.println("甲方:使用乙方公钥加密消息:" + Base64.toBase64String(aEncrypt));System.out.println("乙方:使用乙方私钥解密消息:" + new String(bDecrypt));
}

执行结果

乙方公钥:MHYwTwYGKw4HAgEBMEUCIQD3Tow0iMrSnqcab/qk3sixGNZsFqerw5TZS8AthdG9/wIgVwGItAIOERVrOUQuvYUf4iBgNedVcIVEMpmCAAF67GsDIwACICuSrF+jA6g2XGfFjtP8zmZWA0LstwQQgsMBB6AYuA1/
乙方私钥:MHgCAQAwTwYGKw4HAgEBMEUCIQD3Tow0iMrSnqcab/qk3sixGNZsFqerw5TZS8AthdG9/wIgVwGItAIOERVrOUQuvYUf4iBgNedVcIVEMpmCAAF67GsEIgIgS99qTF3QgAjIKNcpPaA5jnTSp6AUOqb1XhOGGtr75iw=
甲方:使用乙方公钥加密消息:3sdh+pOViDQWU8aDO/LC1SnK427qrFc8PHrMVyE+k7MbL7tQHbq+5I7MZ0vz7WAc6ysAvVZU9pg8YcQvoYWoEw==
乙方:使用乙方私钥解密消息:我是阿汤哥

这篇关于PKI - 非对称加密算法的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/935483

相关文章

3.比 HTTP 更安全的 HTTPS(工作原理理解、非对称加密理解、证书理解)

所谓的协议 协议只是一种规则,你不按规则来就无法和目标方进行你的工作 协议说白了只是人定的规则,任何人都可以定协议 我们不需要太了解细节,这些制定和完善协议的人去做的,我们只需要知道协议的一个大概 HTTPS 协议 1、概述 HTTPS(Hypertext Transfer Protocol Secure)是一种安全的超文本传输协议,主要用于在客户端和服务器之间安全地传输数据

ja-netfilter的前世今生和非对称加密的欺骗原理

文章目录 ja-netfilter起源官网插件插件配置文件插件的综合应用更多用法 非对称加密欺骗原理非对称加密和数字证书激活过程和欺骗手段分析代码示例第一步:生成自签名证书脚本第二步:使用自签名证书对产品激活信息进行签名 样例数据样例激活码(注:用于代码演示,直接粘贴到JetBrains 家 IDE 中无法完成激活!不用试,肯定提示无效,无法激活!!)样例power.conf(配合ja-ne

AES加密算法说明

首先,我们得了解AES加密算法的一些基本概念。AES是一种对称加密算法,所谓对称,是说它的加密、解密过程使用相同的密钥。还有非对称加密算法,例如RSA,加密解密使用的是公私钥对。 AES同时是一种分组加密算法,分组的长度一般是16字节(128bit)。分组是什么意思呢?假设我有一段很长的明文T,我没法用AES加密整个T,只能将T分成若干16byte的明文组,接着对这些明文组逐个进行加密,得到一堆密

【网络安全】服务基础第一阶段——第十一节:Windows系统管理基础----PKI技术与应用

目录​​​​​​​ 一、加密技术 1.1 基本保密通信模型 1.2 密码学发展 1.2.1 古典密码学(1949年前) 1.2.2 近代密码学(1949~1975年) 1.2.3 现代密码学(1976年以后) 1.3 古典密码 1.3.1 古典密码学的特点: 1.3.2 古典密码学的主要分类 1.4 近代密码学 1.5 现代密码学 1.5.1 非对称密钥密码学的基本概念

【SM系列】简单说说SM2,SM3,SM4加密算法

希望文章能给到你启发和灵感~ 如果觉得文章对你有帮助的话,点赞 + 关注+ 收藏 支持一下博主吧~ 阅读指南 开篇说明一、基础环境说明1.1 硬件环境1.2 软件环境 二、什么是SM2加密?2.1 应用场景2.2 与RSA算法的区别 三、什么是SM3加密?3.1 应用场景 四、什么是SM4加密?4.1 应用场景 五、最后 开篇说明 之前我们说过了几种常见加密算法,今天我

【RSA】简单说说什么是RSA非对称加密

希望文章能给到你启发和灵感~ 如果觉得文章对你有帮助的话,点赞 + 关注+ 收藏 支持一下博主吧~ 阅读指南 开篇说明一、基础环境说明1.1 硬件环境1.2 软件环境 二、什么是非对称加密2.1 常见的非对称加密有哪些?2.2 哪些场景适合使用非对称加密?2.3 和对称加密的区别是什么? 三、编程中如何实现对称和非对称加密? 开篇说明 加密中,我们常常会见到多种加密形式

加密算法种类

常见的加密算法可以分成三类,对称加密算法,非对称加密算法和哈希算法。 1. 对     称     加       密:加密和解密使用相同密钥的加密算法。     优          缺          点:对称加密算法的优点在于加解密的高速度和使用长密钥时的难破解性。     常见的对称加密算法:DES、3DES、DESX、Blowfish、IDEA、RC4、RC5、RC6和AES。 2

python实现椭圆曲线加密算法(ECC)

目录 椭圆曲线加密算法(ECC)简介ECC的数学基础椭圆曲线的定义ECC的基本操作 ECC加密和解密流程Python面向对象实现ECC加密和解密代码解释场景应用:安全通信总结 椭圆曲线加密算法(ECC)简介 椭圆曲线加密算法(Elliptic Curve Cryptography, ECC)是一种基于椭圆曲线数学结构的公钥加密算法。ECC以其较高的安全性和较小的密钥长度而闻名

国际非对称加密算法

国际非对称加密 RSA算法原理 RSA算法是一种非对称加密算法,它的安全性基于大数分解的困难性。RSA算法的核心是选择两个大质数p和q,计算它们的乘积n=pq,然后选择一个整数e,使得1<e<φ(n)且e与φ(n)互质,其中φ(n)=(p-1)(q-1)。接着计算d,使得d*e mod φ(n)=1,d称为e的模反元素。公钥为(n,e),私钥为(n,d)。 非对称特征 非对称加密算法有两个密

对称加密算法DES、3DES和AES

学习交流关注微信公众号:钟渊博客 1、对称加密算法 1.1 定义 对称加密算法是应用较早的加密算法,技术成熟。在对称加密算法中,数据发信方将明文(原始数据)和加密密钥(mi yue)一起经过特殊加密算法处理后,使其变成复杂的加密密文发送出去。收信方收到密文后,若想解读原文,则需要使用加密用过的密钥及相同算法的逆算法对密文进行解密,才能使其恢复成可读明文。在对称加密算法中,使用的密钥只有一个,