IOS之RSA加密解密与后台之间的双向加密详解

序言

因为项目中需要用到RSA加密,刚开始也是有点乱,这两天也整理的差不多了,希望能帮到大家。
这次先上代码,我想大部分人肯定是着急解决问题,所以不要废话太多。

IOS端

后台是PHP,给我了一段公钥和他用私钥加密后的base64编码,让我先解一下,看看能否解出(请先不要纠结为什么给我公钥解密,公钥私钥都可以解密,具体后面会讲到)。
公钥:


  1. MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC3//sR2tXw0wrC2DySx8vNGlqt

  2. 3Y7ldU9+LBLI6e1KS5lfc5jlTGF7KBTSkCHBM3ouEHWqp1ZJ85iJe59aF5gIB2kl

  3. Bd6h4wrbbHA2XE1sq21ykja/Gqx7/IRia3zQfxGv/qEkyGOx+XALVoOlZqDwh76o

  4. 2n1vP1D+tD3amHsK7QIDAQAB

base64编码后的加密数据(注意:后台给你的一定是经过base64编码后的):

eZVIkIEDb83YfdpOQCTg1SMfJtAHjdl92oKCALYeItxwvvyBsIR/L2e7y1+rXYCztBELXff/L9SijAYrUWOcvPVLPlkJbiJhZjRn+v4L9UeLtSUfO/qv30K3JROb2OniOvRImK3ZcBq319VT8e62zjJscGBIlwfFfMxRVT/mAzY=

下面使用RSA这是一个封装的第三方框架,只需要将下面这两个文件导入到项目中,便可以使用(不用再导入其他的一些框架),别的框架不敢保证能使用,但这个是肯定可以使用的。

1.png

代码:


  1. //公钥

  2. NSString *publicKey = @"MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC3//sR2tXw0wrC2DySx8vNGlqt3Y7ldU9+LBLI6e1KS5lfc5jlTGF7KBTSkCHBM3ouEHWqp1ZJ85iJe59aF5gIB2klBd6h4wrbbHA2XE1sq21ykja/Gqx7/IRia3zQfxGv/qEkyGOx+XALVoOlZqDwh76o2n1vP1D+tD3amHsK7QIDAQAB";

  3. //base64编码后的加密数据

  4. NSString *base64Str = @"eZVIkIEDb83YfdpOQCTg1SMfJtAHjdl92oKCALYeItxwvvyBsIR/L2e7y1+rXYCztBELXff/L9SijAYrUWOcvPVLPlkJbiJhZjRn+v4L9UeLtSUfO/qv30K3JROb2OniOvRImK3ZcBq319VT8e62zjJscGBIlwfFfMxRVT/mAzY=";

  5. //结果:注意,这里是用公钥进行解密的,方法一定要用对

  6. NSString *resultStr = [RSA decryptString:base64Str publicKey:publicKey];

  7. NSLog(@"结果 = %@",resultStr);

打印结果:

2

这只是先进行测试的数据,如果给你私钥解密,就用别的方法,在RSA.h中可以很容易找到。
上面讲述的是单向加密,那么如何进行双向加密呢?

  • 1、  iOS端和后台(这里后台使用的是java,因为我后台语言只会java,效果都是一样的)各生成自己的公钥和私钥。
  • 2、  iOS端生成的公钥和私钥定义为iOSPublicKeyiOSPrivateKeyjava端生成的公钥私钥定义为javaPublicKeyjavaPrivateKey。将iOSPublicKeyjava,让它用iOSPublicKey加密数据传给iOS端,iOS端用iOSPrivateKey解密;java端将javaPublicKeyiOS端,iOS端用javaPublicKey加密数据后上传给javajava端利用javaPrivateKey去解密,这样就实现了数据传输过程中的加密与解密,当然,也不一定非要按照我上面的步骤来,具体情况要和后台商量如何加密。

具体实现:

IOS端

  • 生成公钥和私钥

1)新建文件夹,用来保存生成的私钥和公钥,打开终端 cd 新建,进入到新建文件夹中,openssl,打开openssl

3

  1. genrsa -out rsa_private_key.pem 1024生成私钥

4

  1. pkcs8 -topk8 -inform PEM -in rsa_private_key.pem -outform PEM -nocrypt这步一定要有,需要将私钥转成PKCS8的格式才能使用,此时复制私钥(先复制私钥,然后在4步取出公钥)

5

4)rsa -in rsa_private_key.pem -pubout -out rsa_public_key.pem 生成公钥

6

此时在新建文件夹中会出现两个文件

7

我们用文本编辑器打开便可获取iOS端生成的公钥和私钥。

  • Xcode项目实战

还得利用上面提到的RSA文件


  1. //公钥

  2. NSString *publicKey = @"MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDl5RBHD3abOyeYCOLkaWkpJXgJQfMklOWPmdJAnG1eD6CV+UOpUKMy5LtfGHQEM7ao5x3BpMx4MNRUYVwBAmU84PhwNm6xpTJrg5zZCloFmsX+E5ukWE5YFRu8i5+5d8LuQTTTv4XfzbTCTOhON8uj+ypkomETuVNwgRFVFjHd1QIDAQAB";

  3. //私钥

  4. NSString *privateKey = @"MIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGBAOXlEEcPdps7J5gI4uRpaSkleAlB8ySU5Y+Z0kCcbV4PoJX5Q6lQozLku18YdAQztqjnHcGkzHgw1FRhXAECZTzg+HA2brGlMmuDnNkKWgWaxf4Tm6RYTlgVG7yLn7l3wu5BNNO/hd/NtMJM6E43y6P7KmSiYRO5U3CBEVUWMd3VAgMBAAECgYEAkqHVDQ4O35oOegmI9plJauYsNvNqqzWRalN5aJ6dn3YmPiI8Bt2ZClgcLt6A+UEmy3qGX0HG7Q5wD9X9geNOQB3ZiD/pGAGW08wS/wTxnWSnSBwdtZ03pUttfnFctkxULfDq4iG1ywdjqEk3F8QVFajQ0c76kWbt9LGAv2OGIi0CQQD2CmbVFXy4JeNHK3TDoLMjsUCiLa+qPnyyVDLDG9Ozb7wN2ydTrMhI+0udmjKvy/Lm1E2bKyp42iYuubEqvSAXAkEA7zNZsOgUe0q73sxXqrLQ7Fs7TNtIEXghrGmkVTHN0I7uMKzQ7KEbA6hfcBm4hPMoLa6Ag3m9tiMNBWtDWc/Y8wJAK0//dEl5EC3TSccTohCbGJBukV47i1u+teHuobw3U2I7F7FZxfgntflPAWqQu7PKieob01IRAv9cM2OLFbv/dwJBAIniXedeQMA5ekaaIEbjwQ8eH/bTyJ1ZVH/gfbwmc2+vlJo2ZFCjJcFcA3fJO9ZXnGeI2cfwG22sksr24+IXsAUCQG5yvVIleTDYqWuWVG1Rc8fk5UFjoZzJpp0nil0z+0fR5rogr4fxcH7vbWsE0id7gSvtV7KxPzkvJTpOK3yGDN0=";

  5. //测试要加密的数据

  6. NSString *sourceStr = @"iOS端RSA";

  7. //公钥加密

  8. NSString *encryptStr = [RSA encryptString:sourceStr publicKey:publicKey];

  9. //私钥解密

  10. NSString *decrypeStr = [RSA decryptString:encryptStr privateKey:privateKey];

  11. NSLog(@"加密后的数据 %@ 解密后的数据 %@",encryptStr,decrypeStr);

打印结果:

8

经过测试,私钥和公钥是可以使用的。

JAVA端

我是用的是Eclipse,具体实现方法也是从网上找的,因为打开的东西太多,忘了是哪篇博客了,知道的请联系我,会注明作者的。

  • 前期准备

9

RSAUtils.java代码:


  1. package RSA;

  2. import java.io.ByteArrayOutputStream;

  3. import java.security.Key;

  4. import java.security.KeyFactory;

  5. import java.security.KeyPair;

  6. import java.security.KeyPairGenerator;

  7. import java.security.PrivateKey;

  8. import java.security.PublicKey;

  9. import java.security.Signature;

  10. import java.security.interfaces.RSAPrivateKey;

  11. import java.security.interfaces.RSAPublicKey;

  12. import java.security.spec.PKCS8EncodedKeySpec;

  13. import java.security.spec.X509EncodedKeySpec;

  14. import java.util.HashMap;

  15. import java.util.Map;

  16. import javax.crypto.Cipher;

  17. /** *//**

  18. * <p>

  19. * RSA公钥/私钥/签名工具包

  20. * </p>

  21. * <p>

  22. * 罗纳德·李维斯特(Ron [R]ivest)、阿迪·萨莫尔(Adi [S]hamir)和伦纳德·阿德曼(Leonard [A]dleman)

  23. * </p>

  24. * <p>

  25. * 字符串格式的**在未在特殊说明情况下都为BASE64编码格式<br/>

  26. * 由于非对称加密速度极其缓慢,一般文件不使用它来加密而是使用对称加密,<br/>

  27. * 非对称加密算法可以用来对对称加密的**加密,这样保证**的安全也就保证了数据的安全

  28. * </p>

  29. *

  30. * @author IceWee

  31. * @date 2012-4-26

  32. * @version 1.0

  33. */

  34. public class RSAUtils {

  35. /** *//**

  36. * 加密算法RSA

  37. */

  38. public static final String KEY_ALGORITHM = "RSA";

  39. /** *//**

  40. * 签名算法

  41. */

  42. public static final String SIGNATURE_ALGORITHM = "MD5withRSA";

  43. /** *//**

  44. * 获取公钥的key

  45. */

  46. private static final String PUBLIC_KEY = "RSAPublicKey";

  47. /** *//**

  48. * 获取私钥的key

  49. */

  50. private static final String PRIVATE_KEY = "RSAPrivateKey";

  51. /** *//**

  52. * RSA最大加密明文大小

  53. */

  54. private static final int MAX_ENCRYPT_BLOCK = 117;

  55. /** *//**

  56. * RSA最大解密密文大小

  57. */

  58. private static final int MAX_DECRYPT_BLOCK = 128;

  59. /** *//**

  60. * <p>

  61. * 生成**对(公钥和私钥)

  62. * </p>

  63. *

  64. * @return

  65. * @throws Exception

  66. */

  67. public static Map<String, Object> genKeyPair() throws Exception {

  68. KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance(KEY_ALGORITHM);

  69. keyPairGen.initialize(1024);

  70. KeyPair keyPair = keyPairGen.generateKeyPair();

  71. RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic();

  72. RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate();

  73. Map<String, Object> keyMap = new HashMap<String, Object>(2);

  74. keyMap.put(PUBLIC_KEY, publicKey);

  75. keyMap.put(PRIVATE_KEY, privateKey);

  76. return keyMap;

  77. }

  78. /** *//**

  79. * <p>

  80. * 用私钥对信息生成数字签名

  81. * </p>

  82. *

  83. * @param data 已加密数据

  84. * @param privateKey 私钥(BASE64编码)

  85. *

  86. * @return

  87. * @throws Exception

  88. */

  89. public static String sign(byte[] data, String privateKey) throws Exception {

  90. byte[] keyBytes = Base64Utils.decode(privateKey);

  91. PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes);

  92. KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);

  93. PrivateKey privateK = keyFactory.generatePrivate(pkcs8KeySpec);

  94. Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM);

  95. signature.initSign(privateK);

  96. signature.update(data);

  97. return Base64Utils.encode(signature.sign());

  98. }

  99. /** *//**

  100. * <p>

  101. * 校验数字签名

  102. * </p>

  103. *

  104. * @param data 已加密数据

  105. * @param publicKey 公钥(BASE64编码)

  106. * @param sign 数字签名

  107. *

  108. * @return

  109. * @throws Exception

  110. *

  111. */

  112. public static boolean verify(byte[] data, String publicKey, String sign)

  113. throws Exception {

  114. byte[] keyBytes = Base64Utils.decode(publicKey);

  115. X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes);

  116. KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);

  117. PublicKey publicK = keyFactory.generatePublic(keySpec);

  118. Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM);

  119. signature.initVerify(publicK);

  120. signature.update(data);

  121. return signature.verify(Base64Utils.decode(sign));

  122. }

  123. /** *//**

  124. * <P>

  125. * 私钥解密

  126. * </p>

  127. *

  128. * @param encryptedData 已加密数据

  129. * @param privateKey 私钥(BASE64编码)

  130. * @return

  131. * @throws Exception

  132. */

  133. public static byte[] decryptByPrivateKey(byte[] encryptedData, String privateKey)

  134. throws Exception {

  135. byte[] keyBytes = Base64Utils.decode(privateKey);

  136. PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes);

  137. KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);

  138. Key privateK = keyFactory.generatePrivate(pkcs8KeySpec);

  139. Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());

  140. cipher.init(Cipher.DECRYPT_MODE, privateK);

  141. int inputLen = encryptedData.length;

  142. ByteArrayOutputStream out = new ByteArrayOutputStream();

  143. int offSet = 0;

  144. byte[] cache;

  145. int i = 0;

  146. // 对数据分段解密

  147. while (inputLen - offSet > 0) {

  148. if (inputLen - offSet > MAX_DECRYPT_BLOCK) {

  149. cache = cipher.doFinal(encryptedData, offSet, MAX_DECRYPT_BLOCK);

  150. } else {

  151. cache = cipher.doFinal(encryptedData, offSet, inputLen - offSet);

  152. }

  153. out.write(cache, 0, cache.length);

  154. i++;

  155. offSet = i * MAX_DECRYPT_BLOCK;

  156. }

  157. byte[] decryptedData = out.toByteArray();

  158. out.close();

  159. return decryptedData;

  160. }

  161. /** *//**

  162. * <p>

  163. * 公钥解密

  164. * </p>

  165. *

  166. * @param encryptedData 已加密数据

  167. * @param publicKey 公钥(BASE64编码)

  168. * @return

  169. * @throws Exception

  170. */

  171. public static byte[] decryptByPublicKey(byte[] encryptedData, String publicKey)

  172. throws Exception {

  173. byte[] keyBytes = Base64Utils.decode(publicKey);

  174. X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(keyBytes);

  175. KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);

  176. Key publicK = keyFactory.generatePublic(x509KeySpec);

  177. Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());

  178. cipher.init(Cipher.DECRYPT_MODE, publicK);

  179. int inputLen = encryptedData.length;

  180. ByteArrayOutputStream out = new ByteArrayOutputStream();

  181. int offSet = 0;

  182. byte[] cache;

  183. int i = 0;

  184. // 对数据分段解密

  185. while (inputLen - offSet > 0) {

  186. if (inputLen - offSet > MAX_DECRYPT_BLOCK) {

  187. cache = cipher.doFinal(encryptedData, offSet, MAX_DECRYPT_BLOCK);

  188. } else {

  189. cache = cipher.doFinal(encryptedData, offSet, inputLen - offSet);

  190. }

  191. out.write(cache, 0, cache.length);

  192. i++;

  193. offSet = i * MAX_DECRYPT_BLOCK;

  194. }

  195. byte[] decryptedData = out.toByteArray();

  196. out.close();

  197. return decryptedData;

  198. }

  199. /** *//**

  200. * <p>

  201. * 公钥加密

  202. * </p>

  203. *

  204. * @param data 源数据

  205. * @param publicKey 公钥(BASE64编码)

  206. * @return

  207. * @throws Exception

  208. */

  209. public static byte[] encryptByPublicKey(byte[] data, String publicKey)

  210. throws Exception {

  211. byte[] keyBytes = Base64Utils.decode(publicKey);

  212. X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(keyBytes);

  213. KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);

  214. Key publicK = keyFactory.generatePublic(x509KeySpec);

  215. // 对数据加密

  216. Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());

  217. cipher.init(Cipher.ENCRYPT_MODE, publicK);

  218. int inputLen = data.length;

  219. ByteArrayOutputStream out = new ByteArrayOutputStream();

  220. int offSet = 0;

  221. byte[] cache;

  222. int i = 0;

  223. // 对数据分段加密

  224. while (inputLen - offSet > 0) {

  225. if (inputLen - offSet > MAX_ENCRYPT_BLOCK) {

  226. cache = cipher.doFinal(data, offSet, MAX_ENCRYPT_BLOCK);

  227. } else {

  228. cache = cipher.doFinal(data, offSet, inputLen - offSet);

  229. }

  230. out.write(cache, 0, cache.length);

  231. i++;

  232. offSet = i * MAX_ENCRYPT_BLOCK;

  233. }

  234. byte[] encryptedData = out.toByteArray();

  235. out.close();

  236. return encryptedData;

  237. }

  238. /** *//**

  239. * <p>

  240. * 私钥加密

  241. * </p>

  242. *

  243. * @param data 源数据

  244. * @param privateKey 私钥(BASE64编码)

  245. * @return

  246. * @throws Exception

  247. */

  248. public static byte[] encryptByPrivateKey(byte[] data, String privateKey)

  249. throws Exception {

  250. byte[] keyBytes = Base64Utils.decode(privateKey);

  251. PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes);

  252. KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);

  253. Key privateK = keyFactory.generatePrivate(pkcs8KeySpec);

  254. Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());

  255. cipher.init(Cipher.ENCRYPT_MODE, privateK);

  256. int inputLen = data.length;

  257. ByteArrayOutputStream out = new ByteArrayOutputStream();

  258. int offSet = 0;

  259. byte[] cache;

  260. int i = 0;

  261. // 对数据分段加密

  262. while (inputLen - offSet > 0) {

  263. if (inputLen - offSet > MAX_ENCRYPT_BLOCK) {

  264. cache = cipher.doFinal(data, offSet, MAX_ENCRYPT_BLOCK);

  265. } else {

  266. cache = cipher.doFinal(data, offSet, inputLen - offSet);

  267. }

  268. out.write(cache, 0, cache.length);

  269. i++;

  270. offSet = i * MAX_ENCRYPT_BLOCK;

  271. }

  272. byte[] encryptedData = out.toByteArray();

  273. out.close();

  274. return encryptedData;

  275. }

  276. /** *//**

  277. * <p>

  278. * 获取私钥

  279. * </p>

  280. *

  281. * @param keyMap **对

  282. * @return

  283. * @throws Exception

  284. */

  285. public static String getPrivateKey(Map<String, Object> keyMap)

  286. throws Exception {

  287. Key key = (Key) keyMap.get(PRIVATE_KEY);

  288. return Base64Utils.encode(key.getEncoded());

  289. }

  290. /** *//**

  291. * <p>

  292. * 获取公钥

  293. * </p>

  294. *

  295. * @param keyMap **对 xs

  296. * @return

  297. * @throws Exception

  298. */

  299. public static String getPublicKey(Map<String, Object> keyMap)

  300. throws Exception {

  301. Key key = (Key) keyMap.get(PUBLIC_KEY);

  302. return Base64Utils.encode(key.getEncoded());

  303. }

  304. }

Base64Utils.java 文件代码:


  1. package RSA;

  2. import java.io.ByteArrayInputStream;

  3. import java.io.ByteArrayOutputStream;

  4. import java.io.File;

  5. import java.io.FileInputStream;

  6. import java.io.FileOutputStream;

  7. import java.io.InputStream;

  8. import java.io.OutputStream;

  9. import it.sauronsoftware.base64.Base64;

  10. public class Base64Utils {

  11. /** *//**

  12. * 文件读取缓冲区大小

  13. */

  14. private static final int CACHE_SIZE = 1024;

  15. /** *//**

  16. * <p>

  17. * BASE64字符串解码为二进制数据

  18. * </p>

  19. *

  20. * @param base64

  21. * @return

  22. * @throws Exception

  23. */

  24. public static byte[] decode(String base64) throws Exception {

  25. return Base64.decode(base64.getBytes());

  26. }

  27. /** *//**

  28. * <p>

  29. * 二进制数据编码为BASE64字符串

  30. * </p>

  31. *

  32. * @param bytes

  33. * @return

  34. * @throws Exception

  35. */

  36. public static String encode(byte[] bytes) throws Exception {

  37. return new String(Base64.encode(bytes));

  38. }

  39. /** *//**

  40. * <p>

  41. * 将文件编码为BASE64字符串

  42. * </p>

  43. * <p>

  44. * 大文件慎用,可能会导致内存溢出

  45. * </p>

  46. *

  47. * @param filePath 文件绝对路径

  48. * @return

  49. * @throws Exception

  50. */

  51. public static String encodeFile(String filePath) throws Exception {

  52. byte[] bytes = fileToByte(filePath);

  53. return encode(bytes);

  54. }

  55. /** *//**

  56. * <p>

  57. * BASE64字符串转回文件

  58. * </p>

  59. *

  60. * @param filePath 文件绝对路径

  61. * @param base64 编码字符串

  62. * @throws Exception

  63. */

  64. public static void decodeToFile(String filePath, String base64) throws Exception {

  65. byte[] bytes = decode(base64);

  66. byteArrayToFile(bytes, filePath);

  67. }

  68. /** *//**

  69. * <p>

  70. * 文件转换为二进制数组

  71. * </p>

  72. *

  73. * @param filePath 文件路径

  74. * @return

  75. * @throws Exception

  76. */

  77. public static byte[] fileToByte(String filePath) throws Exception {

  78. byte[] data = new byte[0];

  79. File file = new File(filePath);

  80. if (file.exists()) {

  81. FileInputStream in = new FileInputStream(file);

  82. ByteArrayOutputStream out = new ByteArrayOutputStream(2048);

  83. byte[] cache = new byte[CACHE_SIZE];

  84. int nRead = 0;

  85. while ((nRead = in.read(cache)) != -1) {

  86. out.write(cache, 0, nRead);

  87. out.flush();

  88. }

  89. out.close();

  90. in.close();

  91. data = out.toByteArray();

  92. }

  93. return data;

  94. }

  95. /** *//**

  96. * <p>

  97. * 二进制数据写文件

  98. * </p>

  99. *

  100. * @param bytes 二进制数据

  101. * @param filePath 文件生成目录

  102. */

  103. public static void byteArrayToFile(byte[] bytes, String filePath) throws Exception {

  104. InputStream in = new ByteArrayInputStream(bytes);

  105. File destFile = new File(filePath);

  106. if (!destFile.getParentFile().exists()) {

  107. destFile.getParentFile().mkdirs();

  108. }

  109. destFile.createNewFile();

  110. OutputStream out = new FileOutputStream(destFile);

  111. byte[] cache = new byte[CACHE_SIZE];

  112. int nRead = 0;

  113. while ((nRead = in.read(cache)) != -1) {

  114. out.write(cache, 0, nRead);

  115. out.flush();

  116. }

  117. out.close();

  118. in.close();

  119. }

  120. }

Test.java文件中


  1. package RSA;

  2. import java.util.Map;

  3. public class Test {

  4. static String publicKey;

  5. static String privateKey;

  6. static {

  7. try {

  8. Map<String, Object> keyMap = RSAUtils.genKeyPair();

  9. publicKey = RSAUtils.getPublicKey(keyMap);

  10. privateKey = RSAUtils.getPrivateKey(keyMap);

  11. System.err.println("公钥: \n\r" + publicKey);

  12. System.err.println("私钥: \n\r" + privateKey);

  13. } catch (Exception e) {

  14. e.printStackTrace();

  15. }

  16. }

  17. public static void main(String[] args) throws Exception {

  18. test();

  19. }

  20. //加密数据

  21. static void test() throws Exception {

  22. String source = "Java端RSA";

  23. System.out.println("\r加密前文字:\r\n" + source);

  24. byte[] data = source.getBytes();

  25. byte[] encodedData = RSAUtils.encryptByPrivateKey(data,privateKey);

  26. System.out.println("加密后文字:\r\n" + new String(encodedData));

  27. byte[] decodedData = RSAUtils.decryptByPublicKey(encodedData, publicKey);

  28. String target = new String(decodedData);

  29. System.out.println("解密后文字: \r\n" + target);

  30. }

  31. //验证签名

  32. static void testSign() throws Exception {

  33. System.err.println("私钥加密——公钥解密");

  34. String source = "这是一行测试RSA数字签名的无意义文字";

  35. System.out.println("原文字:\r\n" + source);

  36. byte[] data = source.getBytes();

  37. byte[] encodedData = RSAUtils.encryptByPrivateKey(data, privateKey);

  38. System.out.println("加密后:\r\n" + new String(encodedData));

  39. byte[] decodedData = RSAUtils.decryptByPublicKey(encodedData, publicKey);

  40. String target = new String(decodedData);

  41. System.out.println("解密后: \r\n" + target);

  42. System.err.println("私钥签名——公钥验证签名");

  43. String sign = RSAUtils.sign(encodedData, privateKey);

  44. System.err.println("签名:\r" + sign);

  45. boolean status = RSAUtils.verify(encodedData, publicKey, sign);

  46. System.err.println("验证结果:\r" + status);

  47. }

  48. }

打印结果:

10

在此,我们可以获取java端生成的私钥和公钥
javaPrivateKey:


  1. MIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGBAICJzSMJQJWRMP/eAQpHpeFvoZ6TlEpDwzOu7U7COK0QFOfbSqw8+jVckcUXsbIeluay5kQBogrlzcBcEOUabMczFQRsb9Lo9fa1TObDPOb+Vexg2ndk6BjGO85npXTQlRx1PQzJ2JoFWjdwFxUX9bgkeZLgkYyPpQroHK4SIe5HAgMBAAECgYAYl8T67htAQp5IZjZ2vAyd3Fjk2UGnD936Nn7K8dgcLJaDYe6gk64fpY1yUz05YibnDtWFr3ZMdXlvU24cF3k2PoIyu/CK+/HxToAI1kx0yk52QdiBfiG9vPIqZmCCDWYm0kLE1ayEt2JMDbMWqlMfA7LWzlFEPsO63Jc4hH0BOQJBAPul4inORuoDgtBPxPGUcCICJJZ0xw+kFxgZjSnV0qcP3nQDdzqLiPPJ9Z8jJziIUEqXaxI0qOG7OFlMW8os5qUCQQCCwuBk/Gve/z+j386yiaJFQwxH8SAO97FuHDmYPJtdjrX7o6Uboq9GydzrPwNNK1odV4S858pXksZnU7K2lRl7AkEA6cv8i4qyJ8iLSK5T835Nj8sd4wsrxkRVkHZsyGl4BO6hZnex1hq9aoJASVGHpuY+co6rU4bJQK+Icq6WuQduYQJAaVcM5s3jKNaAMkhOf84ZB6sn7Zz2spggPBBI5beNgiVBveLrVAQPJ/vfGTS+OCDAi/rBWF1yyHHZm8v1oNkkmQJBAPJ5eXbeQngp3s4fi4wc+RuaXVpnwv1HHsUc3JlxfIRcuLthNKZJdLbQO8tjCfnEjztweJP6HjaO6VxZ50o/EDw=

javaPublicKey:


上面的只是生成公钥和私钥并且是在当前环境测试,也就是iOS测试自己的,Java测试自己的,我上面也已经说了,iOS端与后台如何进行双向加密的,下面具体测试。

双向加密

  • iOS端加密,Java端解密
    iOS端利用javaPublicKey加密数据

11

java端利用javaPrivate解密

12

打印结果:

13

  • Java端加密,iOS端解密
    Java端利用 iOSPublicKey加密

14

15

iOS端利用iOSPrivateKey解密

16

打印结果:

17

最后

至此,单向加密与双向加密,尤其是与后台之间的加密已经讲完了,因为之前看过一些文章有的很模糊,双向加密的讲解很少,并且一些文章的编辑格式真的是难看,根本就没办法看下去,所以花了一点时间讲讲我对这方面的理解,知识其实很浅,并不高深。
注意点:
1、关于iOS端保存的私钥和公钥最好是生成文件保存,并且设置密码,这样为了更安全,这个网上都有,可以找找。
2、在RSA原理上公钥和私钥是可以互相加密互相解密的。公钥加密,私钥解密一般是用于加密数据的,私钥加密公钥解密是用于验证身份的,也就是验证签名。但在iOS端只能用公钥加密私钥解密(不和后台交互,只是在iOS平台),只能用私钥加密公钥验签,请参考文章。如果是和后台进行加密,无论后台是用公钥加密还是私钥加密,iOS端都是可以解的。这个大家可以试试,在RSA文件中,其实他在RSA.h中已经说明了
// enc with private key NOT working YET!
+ (NSString *)encryptString:(NSString *)str privateKey:(NSString *)privKey;
用私钥加密的方法并未实现,具体iOS为何不能用私钥加密公钥解密还在搜索资料中,如果有知道的童鞋请告知,不胜感谢。
8月4日解答:关于非对称加密是没有说用私钥加密公钥解密的,私钥只能用来解密和生成签名,公钥只能用来加密和验签,特此声明!

IOS之RSA加密解密与后台之间的双向加密详解相关推荐

  1. iOS开发 RSA加密解密与后台之间的双向加密详解

    转载自:https://www.jianshu.com/p/43f7fc8d8e14 序言 因为项目中需要用到RSA加密,刚开始也是有点乱,这两天也整理的差不多了,希望能帮到大家.这次先上代码,我想大 ...

  2. 网络通信中的加密解密及openssl和创建私有CA详解

    本文大纲: 1.为什么网络通信要进行数据加密? 2.数据加密方式有哪些?它们是如何进行加密的? 3.通信中是如何进行数据加密传输的? 4.https方式进行数据传输的具体流程 5.SSL 的实现工具O ...

  3. 全网最全之接口测试【加密解密攻防完整版】实战教程详解

    看视频讲的更详细:https://www.bilibili.com/video/BV1zr4y1E7V5/? 一.对称加密 对称加密算法是共享密钥加密算法,在加密解密过程中,使用的密钥只有一个.发送和 ...

  4. 【Android 安全】DEX 加密 ( Java 工具开发 | 加密解密算法 API | 编译代理 Application 依赖库 | 解压依赖库 aar 文件 )

    文章目录 一.加密解密算法 API 二.编译代理 Application 依赖库 三.解压代理 Application 依赖库 aar 文件 参考博客 : [Android 安全]DEX 加密 ( 常 ...

  5. php结合md5的加密解密,php结合md5实现的加密解密方法,php结合md5加密解密_PHP教程...

    php结合md5实现的加密解密方法,php结合md5加密解密 本文实例讲述了php结合md5实现的加密解密方法.分享给大家供大家参考,具体如下: 最近在整理代码发现了一个不错的东西,结合md5的加解密 ...

  6. php 密匙加密解密,带密匙的php加密解密示例分享

    这篇文章主要介绍了php加密解密示例,大家参考使用吧 复制代码 代码如下: /************************************************************* ...

  7. 【Kotlin】加密解密2:DES、AES加密和解密

    文章目录 Api文档 DES加密解密 Base64加密和解密 AES加密解密 DES和AES密钥长度 工作模式和填充模式 对称加密的应用场景 Api文档 https://docs.oracle.com ...

  8. 转:iOS应用程序生命周期(前后台切换,应用的各种状态)详解

    iOS应用程序生命周期(前后台切换,应用的各种状态)详解 分类: iOS开发进阶2012-10-08 15:35 42691人阅读 评论(30) 收藏 举报 iosapplication任务anima ...

  9. java后台验证不能为空_java validation 后台参数验证的使用详解

    一.前言 在后台开发过程中,对参数的校验成为开发环境不可缺少的一个环节.比如参数不能为null,email那么必须符合email的格式,如果手动进行if判断或者写正则表达式判断无意开发效率太慢,在时间 ...

最新文章

  1. juniper srx系列配置端口映射 转载
  2. Windows下配置Java开发环境
  3. X Shell 4配色方案[Solarized Dark]
  4. C语言两种导入头文件的区别
  5. 【转】IT名企面试:腾讯笔试题(2)
  6. 远程仓库都不知道,那你学Git干嘛?
  7. Part 1 – Reverse engineering using Androguard
  8. 1019 General Palindromic Number (20分)_18行代码AC
  9. 微软正在用实际行动告诉你: 拥抱开源,微软是认真的
  10. python:将时间戳转换成格式化日期
  11. python基础课程4(看代码看注释)--爬虫爬取网页信息
  12. CSocket,CAsyncSocket多线程退出时的一些注意事项(解决关闭WinSoket崩溃的问题)
  13. 贪心法——LeetCode 55 跳跃游戏
  14. 第三篇:C++ 中的几种初始化
  15. 用Visual Studio写PHP代码
  16. Redis集群方案介绍
  17. 以ASK调制解调为例观察采样与成型滤波的MATLAB仿真
  18. tomcat乱码问题
  19. Unity播放服务器端视频 发布到Android移动端
  20. 计算机控制键功能,电脑ctrl键的作用大全

热门文章

  1. 我,一个996的普通程序员,如何在2年内买车买房,走向人生巅峰?
  2. esclipse 配置黑色主题
  3. 国家重点研发计划区块链重点专项启动 长安链赋能国家区块链研发
  4. 函数式编程的几点建议
  5. reactos操作系统实现(3)
  6. 故障:部署 Exchange SU 后不能登录到 OWA 或 ECP
  7. 新浪微博客户端开发开篇
  8. gm怎么刷东西 rust_我想知道GM刷装备的命令,越多越好,最好是1-13套全能刷的...
  9. vlc视频流转虚拟摄像头
  10. 联想Yoga 13s重装系统