Android数据传输加密(三):RSA加密

原文地址:https://blog.csdn.net/jungle_pig/article/details/72621237

1.RSA简介

RSA是一种非对称加密算法,加密和解密使用不同的密钥。通信双方各握有一对密钥(称为公钥和私钥)中的一把,己方密钥加密的数据,只有对方密钥能够解密。RSA基于一个数论事实:将两个大素数相乘十分容易,但想要对其乘积进行因式分解却极其困 难,因此可以将乘积公开作为加密密钥,即公钥,而两个大素数组合成私钥。公钥是可提供给任何人使用,私钥则为自己所有,供解密之用。

假使甲方握有公钥,乙方握有私钥,则通信过程如下:

甲方发送数据给乙方。


已方发送数据给甲方。


2. ☆ Android中的使用

产生秘钥对,进而得到公钥和私钥:

[java]  view plain  copy
  1. /* 
  2.        产生密钥对 
  3.        @param keyLength 
  4.        密钥长度,小于1024长度的密钥已经被证实是不安全的,通常设置为1024或者2048,建议2048 
  5.     */  
  6.    public static KeyPair generateRSAKeyPair(int keyLength){  
  7.        KeyPair keyPair = null;  
  8.        try {  
  9.   
  10.            KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");  
  11.            //设置密钥长度  
  12.            keyPairGenerator.initialize(keyLength);  
  13.            //产生密钥对  
  14.            keyPair = keyPairGenerator.generateKeyPair();  
  15.   
  16.        } catch (NoSuchAlgorithmException e) {  
  17.            e.printStackTrace();  
  18.        }  
  19.   
  20.        return keyPair;  
  21.    }  
[java]  view plain  copy
  1. KeyPair keyPair = RSAUtil.generateRSAKeyPair(2048);  
  2. PublicKey publicKey = keyPair.getPublic();  
  3. PrivateKey privateKey = keyPair.getPrivate();  

先写一个加解密通用方法:

[java]  view plain  copy
  1.     /* 
  2.         加密或解密数据的通用方法 
  3.         @param srcData 
  4.         待处理的数据 
  5.         @param key 
  6.         公钥或者私钥 
  7.         @param mode 
  8.         指定是加密还是解密,值为Cipher.ENCRYPT_MODE或者Cipher.DECRYPT_MODE 
  9.  
  10.      */  
  11.     private static byte[] processData(byte[] srcData, Key key,int mode){  
  12.   
  13.         //用来保存处理结果  
  14.         byte[] resultBytes = null;  
  15.   
  16.         try {  
  17.   
  18.             //构建Cipher对象,需要传入一个字符串,格式必须为"algorithm/mode/padding"或者"algorithm/",意为"算法/加密模式/填充方式"  
  19.             Cipher cipher = Cipher.getInstance("RSA/NONE/PKCS1Padding");  
  20.             //初始化Cipher,mode指定是加密还是解密,key为公钥或私钥  
  21.             cipher.init(mode,key);  
  22.             //处理数据  
  23.             resultBytes = cipher.doFinal(srcData);  
  24.   
  25.         } catch (NoSuchAlgorithmException e) {  
  26.             e.printStackTrace();  
  27.         } catch (NoSuchPaddingException e) {  
  28.             e.printStackTrace();  
  29.         } catch (InvalidKeyException e) {  
  30.             e.printStackTrace();  
  31.         } catch (BadPaddingException e) {  
  32.             e.printStackTrace();  
  33.         } catch (IllegalBlockSizeException e) {  
  34.             e.printStackTrace();  
  35.         }  
  36.   
  37.         return resultBytes;  
  38.     } 

注意:获取Cipher实例时,传入的字符串并不是任意的,例如Cipher.getInstance("RSA"),首先,格式要固定,必须为"algorithm/mode/padding"或者"algorithm",意为"算法/加密模式/填充方式"。其次,需要Android支持该组合模式。如何知道android是否支持呢,Cipher的Api文档给出了答案,下面列出关于RSA的所有合法形式:


好了,咱们分情况进行加解密操作。

情况A:公钥加密,私钥解密。

A - 1 公钥加密:

[java]  view plain  copy
  1.      /* 
  2.         使用公钥加密数据,结果用Base64转码 
  3.      */  
  4.     public static String encryptDataByPublicKey(byte[] srcData, PublicKey publicKey){  
  5.   
  6.         byte[] resultBytes = processData(srcData,publicKey,Cipher.ENCRYPT_MODE);  
  7.   
  8.         return Base64.encodeToString(resultBytes,Base64.DEFAULT);  
  9.   
  10.     }

A - 2 私钥解密:

[java]  view plain  copy
  1.      /* 
  2.         使用私钥解密,返回解码数据 
  3.      */  
  4.     public static byte[] decryptDataByPrivate(String encryptedData, PrivateKey privateKey){  
  5.   
  6.         byte[] bytes = Base64.decode(encryptedData,Base64.DEFAULT);  
  7.   
  8.         return processData(bytes,privateKey,Cipher.DECRYPT_MODE);  
  9.     }  
  10.   
  11.     /* 
  12.         使用私钥进行解密,解密数据转换为字符串,使用utf-8编码格式 
  13.      */  
  14.     public static String decryptedToStrByPrivate(String encryptedData, PrivateKey privateKey){  
  15.         return new String(decryptDataByPrivate(encryptedData,privateKey));  
  16.     }  
  17.   
  18.     /* 
  19.         使用私钥解密,解密数据转换为字符串,并指定字符集 
  20.      */  
  21.     public static String decryptedToStrByPrivate(String encryptedData, PrivateKey privateKey,String charset){  
  22.         try {  
  23.   
  24.             return new String(decryptDataByPrivate(encryptedData,privateKey),charset);  
  25.   
  26.         } catch (UnsupportedEncodingException e) {  
  27.             e.printStackTrace();  
  28.         }  
  29.   
  30.         return null;  
  31.     }

情况B:私钥加密,公钥解密。

B - 1 私钥加密:

[java]  view plain  copy
  1.      /* 
  2.         使用私钥加密,结果用Base64转码 
  3.      */  
  4.   
  5.     public static String encryptDataByPrivateKey(byte[] srcData,PrivateKey privateKey){  
  6.   
  7.         byte[] resultBytes = processData(srcData,privateKey,Cipher.ENCRYPT_MODE);  
  8.   
  9.         return Base64.encodeToString(resultBytes,Base64.DEFAULT);  
  10.     }
B - 2 公钥解密:
[java]  view plain  copy
  1.      /* 
  2.         使用公钥解密,返回解密数据 
  3.      */  
  4.   
  5.     public static byte[] decryptDataByPublicKey(String encryptedData,PublicKey publicKey){  
  6.   
  7.         byte[] bytes = Base64.decode(encryptedData,Base64.DEFAULT);  
  8.   
  9.         return processData(bytes,publicKey,Cipher.DECRYPT_MODE);  
  10.   
  11.     }  
  12.   
  13.     /* 
  14.         使用公钥解密,结果转换为字符串,使用默认字符集utf-8 
  15.      */  
  16.     public static String decryptedToStrByPublicKey(String encryptedData,PublicKey publicKey){  
  17.         return new String(decryptDataByPublicKey(encryptedData,publicKey));  
  18.     }  
  19.   
  20.   
  21.     /* 
  22.         使用公钥解密,结果转换为字符串,使用指定字符集 
  23.      */  
  24.   
  25.     public static String decryptedToStrByPublicKey(String encryptedData,PublicKey publicKey,String charset){  
  26.         try {  
  27.   
  28.             return new String(decryptDataByPublicKey(encryptedData,publicKey),charset);  
  29.   
  30.         } catch (UnsupportedEncodingException e) {  
  31.             e.printStackTrace();  
  32.         }  
  33.   
  34.         return null;  
  35.     } 
以上已经给出了产生公、私钥和加解密的方法,然而实际应用中,我们并不会通过代码产生公、私钥对象,而是通过工具(如OpenSSL)生成字符串形式的密钥对,并保存起来使用,由于RSA公钥的特性,我们并不需要担心公钥暴露,可以大胆地亮相在客户端。

通常,我们通过OpenSSL工具生成密钥对字符串,但是过程有点复杂,做过支付宝支付的小伙伴肯定知道,支付宝支付时需要RSA验签,所以支付宝官方提供了一键生成RSA密钥对的工具,下面对该工具进行介绍,如果你对OpenSSL生成密钥对感兴趣,可查看文档:https://docs.open.alipay.com/291/106130

3.利用工具一键生成密钥对

访问支付宝官网,进入如下页面,该页面的URL:https://docs.open.alipay.com/291/105971


点击红圈标注的连接,下载工具,并解压:


进入文件夹,双击RSA签名验签工具.bat运行程序:


程序运行界面:


选择密钥格式和密钥长度,点击生成密钥,即可生成密钥对。点击打开密钥文件路径可找到密钥存储位置:


4.将字符串密钥转换为密钥对象

[java]  view plain  copy
  1.      /* 
  2.         将字符串形式的公钥转换为公钥对象 
  3.      */  
  4.   
  5.     public static PublicKey keyStrToPublicKey(String publicKeyStr){  
  6.   
  7.         PublicKey publicKey = null;  
  8.   
  9.         byte[] keyBytes = Base64.decode(publicKeyStr,sBase64Mode);  
  10.   
  11.         X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes);  
  12.   
  13.         try {  
  14.   
  15.             KeyFactory keyFactory = KeyFactory.getInstance("RSA");  
  16.   
  17.             publicKey = keyFactory.generatePublic(keySpec);  
  18.   
  19.         } catch (NoSuchAlgorithmException e) {  
  20.             e.printStackTrace();  
  21.         } catch (InvalidKeySpecException e) {  
  22.             e.printStackTrace();  
  23.         }  
  24.   
  25.         return publicKey;  
  26.   
  27.     }  
  28.   
  29.     /* 
  30.         将字符串形式的私钥,转换为私钥对象 
  31.      */  
  32.   
  33.     public static PrivateKey keyStrToPrivate(String privateKeyStr){  
  34.   
  35.         PrivateKey privateKey = null;  
  36.   
  37.         byte[] keyBytes = Base64.decode(privateKeyStr,sBase64Mode);  
  38.   
  39.         PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(keyBytes);  
  40.   
  41.         try {  
  42.   
  43.             KeyFactory keyFactory = KeyFactory.getInstance("RSA");  
  44.   
  45.             privateKey = keyFactory.generatePrivate(keySpec);  
  46.   
  47.         } catch (NoSuchAlgorithmException e) {  
  48.             e.printStackTrace();  
  49.         } catch (InvalidKeySpecException e) {  
  50.             e.printStackTrace();  
  51.         }  
  52.   
  53.         return privateKey;  
  54.   
  55.     }
有了公钥和私钥对象,那么我们就可以用之前的方式加密解密了,最后送上完整的工具类:

[java]  view plain  copy
  1. import android.util.Base64;  
  2.   
  3. import java.io.UnsupportedEncodingException;  
  4. import java.security.InvalidKeyException;  
  5. import java.security.Key;  
  6. import java.security.KeyFactory;  
  7. import java.security.KeyPair;  
  8. import java.security.KeyPairGenerator;  
  9. import java.security.NoSuchAlgorithmException;  
  10. import java.security.PrivateKey;  
  11. import java.security.PublicKey;  
  12. import java.security.spec.InvalidKeySpecException;  
  13. import java.security.spec.PKCS8EncodedKeySpec;  
  14. import java.security.spec.X509EncodedKeySpec;  
  15.   
  16. import javax.crypto.BadPaddingException;  
  17. import javax.crypto.Cipher;  
  18. import javax.crypto.IllegalBlockSizeException;  
  19. import javax.crypto.NoSuchPaddingException;  
  20.   
  21. /** 
  22.  * Created by 朱志强 on 2017/5/22. 
  23.  */  
  24.   
  25. public class RSAUtil {  
  26.   
  27.     //构建Cipher实例时所传入的的字符串,默认为"RSA/NONE/PKCS1Padding"  
  28.     private static String sTransform = "RSA/NONE/PKCS1Padding";  
  29.   
  30.     //进行Base64转码时的flag设置,默认为Base64.DEFAULT  
  31.     private static int sBase64Mode = Base64.DEFAULT;  
  32.   
  33.     //初始化方法,设置参数  
  34.     public static void init(String transform,int base64Mode){  
  35.         sTransform = transform;  
  36.         sBase64Mode = base64Mode;  
  37.     }  
  38.   
  39.   
  40.     /* 
  41.         产生密钥对 
  42.         @param keyLength 
  43.         密钥长度,小于1024长度的密钥已经被证实是不安全的,通常设置为1024或者2048,建议2048 
  44.      */  
  45.     public static KeyPair generateRSAKeyPair(int keyLength){  
  46.         KeyPair keyPair = null;  
  47.         try {  
  48.   
  49.             KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");  
  50.             //设置密钥长度  
  51.             keyPairGenerator.initialize(keyLength);  
  52.             //产生密钥对  
  53.             keyPair = keyPairGenerator.generateKeyPair();  
  54.   
  55.         } catch (NoSuchAlgorithmException e) {  
  56.             e.printStackTrace();  
  57.         }  
  58.   
  59.         return keyPair;  
  60.     }  
  61.   
  62.     /* 
  63.         加密或解密数据的通用方法 
  64.         @param srcData 
  65.         待处理的数据 
  66.         @param key 
  67.         公钥或者私钥 
  68.         @param mode 
  69.         指定是加密还是解密,值为Cipher.ENCRYPT_MODE或者Cipher.DECRYPT_MODE 
  70.  
  71.      */  
  72.     private static byte[] processData(byte[] srcData, Key key,int mode){  
  73.   
  74.         //用来保存处理结果  
  75.         byte[] resultBytes = null;  
  76.   
  77.         try {  
  78.   
  79.             //获取Cipher实例  
  80.             Cipher cipher = Cipher.getInstance(sTransform);  
  81.             //初始化Cipher,mode指定是加密还是解密,key为公钥或私钥  
  82.             cipher.init(mode,key);  
  83.             //处理数据  
  84.             resultBytes = cipher.doFinal(srcData);  
  85.   
  86.         } catch (NoSuchAlgorithmException e) {  
  87.             e.printStackTrace();  
  88.         } catch (NoSuchPaddingException e) {  
  89.             e.printStackTrace();  
  90.         } catch (InvalidKeyException e) {  
  91.             e.printStackTrace();  
  92.         } catch (BadPaddingException e) {  
  93.             e.printStackTrace();  
  94.         } catch (IllegalBlockSizeException e) {  
  95.             e.printStackTrace();  
  96.         }  
  97.   
  98.         return resultBytes;  
  99.     }  
  100.   
  101.   
  102.     /* 
  103.         使用公钥加密数据,结果用Base64转码 
  104.      */  
  105.     public static String encryptDataByPublicKey(byte[] srcData, PublicKey publicKey){  
  106.   
  107.         byte[] resultBytes = processData(srcData,publicKey,Cipher.ENCRYPT_MODE);  
  108.   
  109.         return Base64.encodeToString(resultBytes,sBase64Mode);  
  110.   
  111.     }  
  112.   
  113.     /* 
  114.         使用私钥解密,返回解码数据 
  115.      */  
  116.     public static byte[] decryptDataByPrivate(String encryptedData, PrivateKey privateKey){  
  117.   
  118.         byte[] bytes = Base64.decode(encryptedData,sBase64Mode);  
  119.   
  120.         return processData(bytes,privateKey,Cipher.DECRYPT_MODE);  
  121.     }  
  122.   
  123.     /* 
  124.         使用私钥进行解密,解密数据转换为字符串,使用utf-8编码格式 
  125.      */  
  126.     public static String decryptedToStrByPrivate(String encryptedData, PrivateKey privateKey){  
  127.         return new String(decryptDataByPrivate(encryptedData,privateKey));  
  128.     }  
  129.   
  130.     /* 
  131.         使用私钥解密,解密数据转换为字符串,并指定字符集 
  132.      */  
  133.     public static String decryptedToStrByPrivate(String encryptedData, PrivateKey privateKey,String charset){  
  134.         try {  
  135.   
  136.             return new String(decryptDataByPrivate(encryptedData,privateKey),charset);  
  137.   
  138.         } catch (UnsupportedEncodingException e) {  
  139.             e.printStackTrace();  
  140.         }  
  141.   
  142.         return null;  
  143.     }  
  144.   
  145.   
  146.     /* 
  147.         使用私钥加密,结果用Base64转码 
  148.      */  
  149.   
  150.     public static String encryptDataByPrivateKey(byte[] srcData,PrivateKey privateKey){  
  151.   
  152.         byte[] resultBytes = processData(srcData,privateKey,Cipher.ENCRYPT_MODE);  
  153.   
  154.         return Base64.encodeToString(resultBytes,sBase64Mode);  
  155.     }  
  156.   
  157.     /* 
  158.         使用公钥解密,返回解密数据 
  159.      */  
  160.   
  161.     public static byte[] decryptDataByPublicKey(String encryptedData,PublicKey publicKey){  
  162.   
  163.         byte[] bytes = Base64.decode(encryptedData,sBase64Mode);  
  164.   
  165.         return processData(bytes,publicKey,Cipher.DECRYPT_MODE);  
  166.   
  167.     }  
  168.   
  169.     /* 
  170.         使用公钥解密,结果转换为字符串,使用默认字符集utf-8 
  171.      */  
  172.     public static String decryptedToStrByPublicKey(String encryptedData,PublicKey publicKey){  
  173.         return new String(decryptDataByPublicKey(encryptedData,publicKey));  
  174.     }  
  175.   
  176.   
  177.     /* 
  178.         使用公钥解密,结果转换为字符串,使用指定字符集 
  179.      */  
  180.   
  181.     public static String decryptedToStrByPublicKey(String encryptedData,PublicKey publicKey,String charset){  
  182.         try {  
  183.   
  184.             return new String(decryptDataByPublicKey(encryptedData,publicKey),charset);  
  185.   
  186.         } catch (UnsupportedEncodingException e) {  
  187.             e.printStackTrace();  
  188.         }  
  189.   
  190.         return null;  
  191.     }  
  192.   
  193.   
  194.   
  195.   
  196.     /* 
  197.         将字符串形式的公钥转换为公钥对象 
  198.      */  
  199.   
  200.     public static PublicKey keyStrToPublicKey(String publicKeyStr){  
  201.   
  202.         PublicKey publicKey = null;  
  203.   
  204.         byte[] keyBytes = Base64.decode(publicKeyStr,sBase64Mode);  
  205.   
  206.         X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes);  
  207.   
  208.         try {  
  209.   
  210.             KeyFactory keyFactory = KeyFactory.getInstance("RSA");  
  211.   
  212.             publicKey = keyFactory.generatePublic(keySpec);  
  213.   
  214.         } catch (NoSuchAlgorithmException e) {  
  215.             e.printStackTrace();  
  216.         } catch (InvalidKeySpecException e) {  
  217.             e.printStackTrace();  
  218.         }  
  219.   
  220.         return publicKey;  
  221.   
  222.     }  
  223.   
  224.     /* 
  225.         将字符串形式的私钥,转换为私钥对象 
  226.      */  
  227.   
  228.     public static PrivateKey keyStrToPrivate(String privateKeyStr){  
  229.   
  230.         PrivateKey privateKey = null;  
  231.   
  232.         byte[] keyBytes = Base64.decode(privateKeyStr,sBase64Mode);  
  233.   
  234.         PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(keyBytes);  
  235.   
  236.         try {  
  237.   
  238.             KeyFactory keyFactory = KeyFactory.getInstance("RSA");  
  239.   
  240.             privateKey = keyFactory.generatePrivate(keySpec);  
  241.   
  242.         } catch (NoSuchAlgorithmException e) {  
  243.             e.printStackTrace();  
  244.         } catch (InvalidKeySpecException e) {  
  245.             e.printStackTrace();  
  246.         }  
  247.   
  248.         return privateKey;  
  249.   
  250.     }  
  251.   
  252. }

利用生成的密钥对,测试一下工具类:

[java]  view plain  copy
  1. public class MainActivity extends AppCompatActivity {  
  2.     //字符串公钥,可以直接保存在客户端  
  3.     public static final String PUBLIC_KEY_STR = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEArDq+LD0E5aRw9O6oElL2jvb7OGxOACxdcZZnvwN4L+Pv3aM4KSGl4Q7zDSAj/ViaQDC6Y0f3GXiAPIoGPcUnIcm/mpiNZ85NHgoYtgwpP4o0nAEarEUu/YPfdzYAVF7ku+azVJPxelbgxQV0tlamKk0H1COHi3nIdgbusaAvEarMZfFMk25MKB03LrWBjJ9ydDFOjvfokigdxvBDmFhyTsgU1QlEsDPKNFqRS+nrDx6z6j5Xpfeq3P59sQJLE3Hd6YGbUxJB4eVDua5KWS6Fw/5mFWfGBQmdMqm4dUEXlCAYr1U6GVtJJ+amSfzwP1U2D5KD7xCy8N3MJRlgsN2iFwIDAQAB";  
  4.     //字符串密钥,通常保存在服务器,这里为了方便演示,直接保存在客户端  
  5.     public static final String PRIVATE_KEY_STR = "MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQCsOr4sPQTlpHD07qgSUvaO9vs4bE4ALF1xlme/A3gv4+/dozgpIaXhDvMNICP9WJpAMLpjR/cZeIA8igY9xSchyb+amI1nzk0eChi2DCk/ijScARqsRS79g993NgBUXuS75rNUk/F6VuDFBXS2VqYqTQfUI4eLech2Bu6xoC8Rqsxl8UyTbkwoHTcutYGMn3J0MU6O9+iSKB3G8EOYWHJOyBTVCUSwM8o0WpFL6esPHrPqPlel96rc/n2xAksTcd3pgZtTEkHh5UO5rkpZLoXD/mYVZ8YFCZ0yqbh1QReUIBivVToZW0kn5qZJ/PA/VTYPkoPvELLw3cwlGWCw3aIXAgMBAAECggEABrWPHPgPjcaXI+N8JqKWukECzlLhwv33cepTBkzjTLJLcM3f7TJDXP4RF8zNuhvOfnundyChjpt0G2ehEJzyhk1uql4Q/B88P9RS3ByjKrd+jyk32cgkKXoOpX00DBVaQbud9siAmqxxuxsYTdYYSQORL4Fm0VcgKQDiIYdE7iIx0G+CTO8ClWKNwQsY82GdEd1DizGVz7p747k5doSiSi6Bu7YHXk9d5kiFeGhBRXO2KQt2ZfyVsRbDuKdyWvpMeRKFE8dsSvgEC1Cli8ThGjPM1PLJYmkWRGwFu+Rorua04u6ss6zqEam08pOm0qzfoKJ7ZvaiIhbecjadRC9qeQKBgQDYBeDxPQu1IwA92KtcazSCGXCk4cf3IqlDnlT/kVTdy5RsVa93mq2KAYSlTOq+6b58qPP5RlNx0kbWZUo4eyqy3s7GHcDI9kkSgljUKUboFNvtD4ROMgJ8f8xauEsKb1MOkS940JTJ4OfdzHfzOLj/DTfyxFl58AJGfUyi7hfJQwKBgQDMGiPvzJPFzvOL+jQPbF3B+ttlJLOAmHpgzlkqlWTD3EQC7EW9AZiuIlk0mgxXMWkULvpn2sem3/RwTbUp6omaz2/vWZE9UXUvLXAMWy44zNNaXUP/rROxvpFXuvD63N2BevHzL4t2GDCO54yrXq5vNkjqRBTee8sfqxpOLP68nQKBgQCqIh8h/6Eb3OAQ1XdIh0pIeH7F7OhPVGYY0jdBPJWpRO+1TtquCQ1KFp4Ajg6Ho5IZnfrgRSntB94wdn+48hAT5fTWBZLS811jjXMmTQgCOoNnNgROjYZ1xTUN8f1vz3OLkn7f2O6F/HLAtYt27CKPBTseINQTfBpep8pWu8vR/wKBgBWB46uPSTsc9bkYYogFiVO5lYjw9yFj7/FnjSnZmEazXU9ZinfCRU6EPBY47Xf6svH3iVeMTGGfU+jJp3+FQX7YwRjdvVpSzSBtj1MeAJ7nppXtIg89M8gVJsex4VbuE0FjrT9NEUsefW9xovckAQmjFMfq6LARJ3Rs2VbHkwhZAoGBANOj4V5tJzcZmoav14WfNTs5EPq+W8ZR73NDaffTq5oWytqYaQoG/haISANySHL5mF+PIZ5lKBRHnzO6u2tk+ir/LjmMqJT5WzhtQqAv8jkogkxzD8nyXtiIyRyf8s/oI2UQwdNWIxqQKLIrqGQ2HCuSC1QquZD1EmuIYjE6/w5j";  
  6.     @Override  
  7.     protected void onCreate(Bundle savedInstanceState) {  
  8.         super.onCreate(savedInstanceState);  
  9.         setContentView(R.layout.activity_main);  
  10.   
  11.         Logger.init("朱志强");  
  12.   
  13.         //获取公钥  
  14.         PublicKey publicKey = RSAUtil.keyStrToPublicKey(PUBLIC_KEY_STR);  
  15.         //获取私钥  
  16.         PrivateKey privateKey = RSAUtil.keyStrToPrivate(PRIVATE_KEY_STR);  
  17.   
  18.         //需要加密的数据  
  19.         String clearText01 = "大家好,我是朱志强!";  
  20.   
  21.         //公钥加密结果  
  22.         String publicEncryptedResult = RSAUtil.encryptDataByPublicKey(clearText01.getBytes(),publicKey);  
  23.         //私钥解密结果  
  24.         String privateDecryptedResult = RSAUtil.decryptedToStrByPrivate(publicEncryptedResult,privateKey);  
  25.   
  26.         Logger.d("公钥加密,私钥解密测试:\n"  
  27.                     + "原文:\n" + clearText01 + "\n"  
  28.                     + "公钥加密结果:\n" + publicEncryptedResult + "\n"  
  29.                     + "私钥解密结果:\n" + privateDecryptedResult  
  30.                 );  
  31.   
  32.   
  33.         //需要加密的数据  
  34.         String clearText02 = "希望大家多多支持我的博客,不足之处还望斧正!";  
  35.   
  36.         //私钥加密结果  
  37.         String privateEncryptedResult = RSAUtil.encryptDataByPrivateKey(clearText02.getBytes(),privateKey);  
  38.         //公钥解密结果  
  39.         String publicDecryptedResult = RSAUtil.decryptedToStrByPublicKey(privateEncryptedResult,publicKey);  
  40.   
  41.         Logger.d("私钥加密,公钥解密测试:\n"  
  42.                 + "原文:\n" + clearText02 + "\n"  
  43.                 + "私钥加密结果:\n" + privateEncryptedResult + "\n"  
  44.                 + "公钥解密结果:\n" + publicDecryptedResult  
  45.         );  
  46.   
  47.     }  
  48.   

运行结果如下:

5.RSA的局限性

RSA的原理和使用方式决定了它的安全性之高,不过它依然有自己的短板。首先,RSA加解密比较耗时,必然引起性能下降,特别是大并发的服务端来说,影响更加明显。第二,RSA对要加密的数据的长度也有限制,待加密的字节数不能超过密钥的长度值除以 8 再减去 11(即:KeySize / 8 - 11)。


猜你喜欢

转载自blog.csdn.net/dodod2012/article/details/80824601