加解密算法分析( 四 )


非对称加密工作原理下面我们就看一下非对称加密的工作原理 。

  • 乙方生成一对密钥(公钥和私钥)并将公钥向其它方公开 。
  • 得到该公钥的甲方使用该密钥对机密信息进行加密后再发送给乙方 。
  • 乙方再用自己保存的另一把专用密钥(私钥)对加密后的信息进行解密 。乙方只能用其专用密钥(私钥)解密由对应的公钥加密后的信息 。
  • 在传输过程中 , 即使攻击者截获了传输的密文 , 并得到了乙的公钥 , 也无法破解密文 , 因为只有乙的私钥才能解密密文 。同样 , 如果乙要回复加密信息给甲 , 那么需要甲先公布甲的公钥给乙用于加密 , 甲自己保存甲的私钥用于解密 。
非对称加密鼻祖:RSARSA算法基于一个十分简单的数论事实:将两个大质数(素数)相乘十分容易 , 但是想要对其乘积进行因式分解却极其困难 , 因此可以将乘积公开作为加密密钥 。比如:取两个简单的质数:67 , 73 , 得到两者乘积很简单4891;但是要想对4891进行因式分解 , 其工作量成几何增加 。
应用场景:
HTTPS请求的SSL层 。
加解密算法分析

文章插图
 
在JDK中也提供了RSA的实现 , 下面给出示例:
Copy /*** 创建密匙对** @return*/private KeyPair genKeyPair() {//创建 RSA Key 的生产者 。KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance("RSA");//利用用户密码作为随机数初始化出 1024 比特 Key 的生产者 。//SecureRandom 是生成安全随机数序列 , password.getBytes() 是种子 , 只要种子相同 , 序列就一样 。keyPairGen.initialize(1024, new SecureRandom("password".getBytes()));//创建密钥对return keyPairGen.generateKeyPair();}/*** 生成公匙** @return*/public PublicKey genPublicKey() {try {//创建密钥对KeyPair keyPair = genKeyPair();//生成公钥PublicKey publicKey = keyPair.getPublic();X509EncodedKeySpec keySpec = new X509EncodedKeySpec(publicKey.getEncoded());KeyFactory keyFactory = KeyFactory.getInstance("RSA");publicKey = keyFactory.generatePublic(keySpec);return publicKey;} catch (Exception e) {e.printStackTrace();}return null;}/*** 生成私匙** @return*/public PrivateKey genPrivateKey() {try {//创建密钥对KeyPair keyPair = genKeyPair();//生成私匙PrivateKey privateKey = keyPair.getPrivate();X509EncodedKeySpec keySpec = new X509EncodedKeySpec(privateKey.getEncoded());KeyFactory keyFactory = KeyFactory.getInstance("RSA");return keyFactory.generatePrivate(keySpec);} catch (Exception e) {e.printStackTrace();}return null;}/*** 公钥加密** @param data* @param publicKey* @return* @throws Exception*/public static byte[] encryptByPublicKey(byte[] data, String publicKey)throws Exception {X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(publicKey.getBytes());KeyFactory keyFactory = KeyFactory.getInstance("RSA");Key publicK = keyFactory.generatePublic(x509KeySpec);// 对数据加密Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());cipher.init(Cipher.ENCRYPT_MODE, publicK);int inputLen = data.length;ByteArrayOutputStream out = new ByteArrayOutputStream();int offSet = 0;byte[] cache;int i = 0;// 对数据分段加密while (inputLen - offSet > 0) {if (inputLen - offSet > 117) {cache = cipher.doFinal(data, offSet, 117);} else {cache = cipher.doFinal(data, offSet, inputLen - offSet);}out.write(cache, 0, cache.length);i++;offSet = i * 117;}byte[] encryptedData = https://www.isolves.com/it/cxkf/sf/2020-06-30/out.toByteArray();out.close();return encryptedData;}/*** 私钥解密** @param encryptedData* @param privateKey* @return* @throws Exception*/public static byte[] decryptByPrivateKey(byte[] encryptedData,String privateKey) throws Exception {PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(privateKey.getBytes());KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);Key privateK = keyFactory.generatePrivate(pkcs8KeySpec);Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());cipher.init(Cipher.DECRYPT_MODE, privateK);int inputLen = encryptedData.length;ByteArrayOutputStream out = new ByteArrayOutputStream();int offSet = 0;byte[] cache;int i = 0;// 对数据分段解密while (inputLen - offSet > 0) {if (inputLen - offSet > 118) {cache = cipher.doFinal(encryptedData, offSet, 118);} else {cache = cipher.doFinal(encryptedData, offSet, inputLen - offSet);}out.write(cache, 0, cache.length);i++;offSet = i * 118;}byte[] decryptedData = out.toByteArray();out.close();return decryptedData;}/*** 私钥加密** @param data* @param privateKey* @return* @throws Exception*/public static byte[] encryptByPrivateKey(byte[] data, String privateKey)throws Exception {PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(publicKey.getBytes());KeyFactory keyFactory = KeyFactory.getInstance("RSA");Key privateK = keyFactory.generatePrivate(pkcs8KeySpec);Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());cipher.init(Cipher.ENCRYPT_MODE, privateK);int inputLen = data.length;ByteArrayOutputStream out = new ByteArrayOutputStream();int offSet = 0;byte[] cache;int i = 0;// 对数据分段加密while (inputLen - offSet > 0) {if (inputLen - offSet > 117) {cache = cipher.doFinal(data, offSet, 117);} else {cache = cipher.doFinal(data, offSet, inputLen - offSet);}out.write(cache, 0, cache.length);i++;offSet = i * 117;}byte[] encryptedData = out.toByteArray();out.close();return encryptedData;} /*** 公钥解密** @param encryptedData* @param publicKey* @return* @throws Exception*/public static byte[] decryptByPublicKey(byte[] encryptedData,String publicKey) throws Exception {X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(publicKey.getBytes());KeyFactory keyFactory = KeyFactory.getInstance("RSA");Key publicK = keyFactory.generatePublic(x509KeySpec);Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());cipher.init(Cipher.DECRYPT_MODE, publicK);int inputLen = encryptedData.length;ByteArrayOutputStream out = new ByteArrayOutputStream();int offSet = 0;byte[] cache;int i = 0;// 对数据分段解密while (inputLen - offSet > 0) {if (inputLen - offSet > 118) {cache = cipher.doFinal(encryptedData, offSet, 118);} else {cache = cipher.doFinal(encryptedData, offSet, inputLen - offSet);}out.write(cache, 0, cache.length);i++;offSet = i * 118;}byte[] decryptedData = out.toByteArray();out.close();return decryptedData;}


推荐阅读