PHP-RSA加密跨域通讯实战


AUTH:PHILO EMAIL:lijianying12 at gmail.com

基于POST GET 的http通讯虽然非常成熟,但是很容易被人监听。 并且如果使用跨域jsonp的通讯很容易在历史记录中发现通讯网址以及参数。为了克服这些问题, 并且降低服务器成本,我们没有使用SSL而使用 RSA加密。文章中的php加密解密 JS的加密解密 互相加密解密 都能验证通过。

其中PHP依赖常见的OPENSSL LIB 。 JS依赖 jsencrypt。

我们使用jsonp get RSA加密通讯好处如下:

  1. 前后分离适合cdn加速。
  2. 安全跨域更适合松散结构的网站。
  3. 不用去买ssl证书了。

首先要生成密匙对

  1. openssl genrsa 1024>private.key
  2. openssl rsa -inprivate.key -pubout >public.key

JS的RSA加密流程

下载最新版本请移步到github:jsencrypt 代码在目录BIN下面是否用压缩的根据情况决定。

生成KEY

  1. var keySize =1024;//加密强度
  2. var crypt =newJSEncrypt({default_key_size: keySize});//RSA 操作对象
  3. //方法1 (async)
  4. crypt.getKey(function(){
  5. crypt.getPrivateKey();
  6. crypt.getPublicKey();
  7. });
  8. //方法2:
  9. crypt.getKey();
  10. crypt.getPrivateKey();
  11. crypt.getPublicKey();

客户端加密场景:

  1. var crypt1 =newJSEncrypt();//新建rsa对象
  2. var publickey ='\
  3. -----BEGIN PUBLIC KEY-----\
  4. MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC3N8LJFqlsa6loCgFpgZVMr/Sx\
  5. DMQY7pr0euNQfh2g+UVPbB0MGhoc7nWL0FQhCgDedbjQw/nGFStFx7W1+0o1oRTY\
  6. u5ebNVivZSobraUv7LJvwT8O66Zs8cxbKLqQ/nE/WwJvXomSIckH6R8iOUO8/QT9\
  7. kv6/L0Uma3qA07pmDQIDAQAB\
  8. -----END PUBLIC KEY-----\
  9. ';
  10. crypt1.setPublicKey(publickey );//添加来自服务端的publickey
  11. crypt1.encrypt('abc');//返回值为加密后的结果

客户端解密场景:

  1. var privatekey ='-----BEGIN RSA PRIVATE KEY-----\
  2. MIICXQIBAAKBgQC3N8LJFqlsa6loCgFpgZVMr/SxDMQY7pr0euNQfh2g+UVPbB0M\
  3. Ghoc7nWL0FQhCgDedbjQw/nGFStFx7W1+0o1oRTYu5ebNVivZSobraUv7LJvwT8O\
  4. 66Zs8cxbKLqQ/nE/WwJvXomSIckH6R8iOUO8/QT9kv6/L0Uma3qA07pmDQIDAQAB\
  5. AoGBAKba3UWModbfZXQeSJLxNCqWw9zJp3ydL/keQQ35DLqgyIJAD2QKEWXvtJUT\
  6. sMo19fyicSGOmFXQyYvPCKkmpLkOMAj1XaNpSMtSrcMx+gC01PO6Ey9rsUxW1g3u\
  7. fpqbEk9E3a5AtCS0I61nbUpRL6rqMtR5o2wcNR3TLtJt7pjxAkEA7hlFJKU1zWGp\
  8. OvvkJDnHc2NOCEJoGjqCR9wwv96+/xAykl2laI6WvEbbhjoO0+8+d17oigjhneS5\
  9. 2UKFcfqw7wJBAMT+MCQ5TYLQlvjrBaDMqOdLsqtaDE6CpkrgwV820QMvHOo3R4Xd\
  10. uSbrA2tOr9t2/x+FzF971lRGdPFIch9UYMMCQQCZtO6SDaWCBP3++gX57OL5dq41\
  11. XsldxU+9nERMWTvr5UUAgDv8F7Dvsr6dFHXmE5i77yUnlzwvdi0UOIF1Z2U5AkBV\
  12. wyRKYPgx34Ya0JcerntKV1Zt60I4XADx0G/feAn/DN/VyENHMISPQPm4GgXN0jy4\
  13. CJQ1bcCd6B65fQTSRvXpAkA2Vv5yXzeKDls/AyxHEoros/VYftVc1HOFC++q13Rw\
  14. NH2rnlRT8FMTFEqL9MYRqvvYAFf5VmH0M1Nx5t4LRN+l\
  15. -----END RSA PRIVATE KEY-----\
  16. ';
  17. var crypt2 =newJSEncrypt();//新建加密对象
  18. crypt2.setPrivateKey(privatekey);//给加密对象设置privatekey
  19. crypt2.getPublicKey();//Tip 我们是不需要存储publickey的直接用private能得到publickey
  20. crypt2.decrypt("MeUqWB5LwTh8crzPqbZtEtKuZxYvPWH9CTCChK1qoBzIgIXGPCdzNMbiH0cCYHl5qWSERIDOgDIgv4dXsIMjEJ5q0cp/qNQYHM5va0iw0UvKvQB1E8aWtY2nFEPy4F+ArQ0Mj/ijr/CntEP1jHKC3WU9nu2kYrBIBnbj14Bs+kI=");//调用解密方法

但是虽然写到了这里,加密方面还是不够用,因为1024长度的RSA加密最多只能加密长度为117的字符串。而URL长度最多为4k因此这里我们要让加密长度达到2691以达到能用的程度。

那么这种加密长度大概能容纳多少数据呢? 我们借助json-generator来帮忙生成JSON

  1. sdata =[
  2. {
  3. "_id":"542f9ac2359c7d881bc0298e",
  4. "index":0,
  5. "guid":"db1dacc1-b870-4e3c-bc1a-80dfd9506610",
  6. "isActive":false,
  7. "balance":"$1,570.15",
  8. "picture":"http://placehold.it/32x32",
  9. "age":36,
  10. "eyeColor":"blue",
  11. "name":"Effie Barr",
  12. "gender":"female",
  13. "company":"ZORK",
  14. "email":"effiebarr@zork.com",
  15. "phone":"+1 (802) 574-3379",
  16. "address":"951 Cortelyou Road, Wikieup, Colorado, 4694",
  17. "about":"Sunt reprehenderit do laboris velit qui elit duis velit qui. Nostrud sit eiusmod cillum exercitation veniam ad sint irure cupidatat sunt consectetur magna. Amet nisi velit laboris amet officia et velit nisi nostrud ipsum. Cupidatat et fugiat esse minim occaecat cillum enim exercitation laboris velit nisi est enim aute. Enim do pariatur\r\n",
  18. "registered":"2014-05-08T15:26:35 -08:00",
  19. "latitude":48.576424,
  20. "longitude":146.634137,
  21. "tags":[
  22. "esse",
  23. "proident",
  24. "quis",
  25. "consectetur",
  26. "magna",
  27. "tempor",
  28. "anim"
  29. ],
  30. "friends":[
  31. {
  32. "id":0,
  33. "name":"Trisha Cannon"
  34. },
  35. {
  36. "id":1,
  37. "name":"Todd Bullock"
  38. },
  39. {
  40. "id":2,
  41. "name":"Eileen Drake"
  42. },
  43. {
  44. "id":3,
  45. "name":"Ferrell Kelly"
  46. },
  47. {
  48. "id":4,
  49. "name":"Fischer Blankenship"
  50. },
  51. {
  52. "id":5,
  53. "name":"Morales Mann"
  54. },
  55. {
  56. "id":6,
  57. "name":"Brandie Pittman"
  58. },
  59. {
  60. "id":7,
  61. "name":"Virgie Kerr"
  62. }
  63. ],
  64. "greeting":"Hello, Effie Barr! You have 1 unread messages.",
  65. "favoriteFruit":"apple"
  66. },
  67. {
  68. "_id":"542f9ac21c260d03e763a4f2",
  69. "index":1,
  70. "guid":"9e3a3d8a-26f8-46b7-aca0-336a194808b1",
  71. "isActive":true,
  72. "balance":"$3,617.89",
  73. "picture":"http://placehold.it/32x32",
  74. "age":31,
  75. "eyeColor":"brown",
  76. "name":"Butler Best",
  77. "gender":"male",
  78. "company":"SPORTAN",
  79. "email":"butlerbest@sportan.com",
  80. "phone":"+1 (905) 428-3046",
  81. "address":"798 Joval Court, Wanship, Delaware, 8974",
  82. "about":"Nostrud occaecat id sunt pariatur ad nisi do veniam sit officia non consequat amet fugiat. Est eiusmod labore ut cillum qui eu elit ut eiusmod exercitation. Ut anim nostrud eiusmod voluptate tempor proident id do pariatur. In Lorem ullamco ea irure adipisicing. Quis est dolor ex commodo aliqua nisi elit sit elit anim fugiat sunt amet. Enim consequat ipsum occaecat ipsum tempor deserunt dolor veniam nostrud. Anim cillum ullamco cupidatat aute velit fugiat sit enim in amet anim mollit dolor eiusmod.\r\n",
  83. "registered":"2014-08-02T06:15:44 -08:00",
  84. "latitude":-20.529765,
  85. "longitude":2.396578,
  86. "tags":[
  87. "consequat",
  88. "enim",
  89. "magna",
  90. "sunt",
  91. "Lorem",
  92. "quis",
  93. "commodo"
  94. ],
  95. "friends":[
  96. {
  97. "id":0,
  98. "name":"Kenya Rice"
  99. },
  100. {
  101. "id":1,
  102. "name":"Hale Knowles"
  103. },
  104. {
  105. "id":2,
  106. "name":"Michael Stephens"
  107. },
  108. {
  109. "id":3,
  110. "name":"Holder Bailey"
  111. },
  112. {
  113. "id":4,
  114. "name":"Garner Luna"
  115. },
  116. {
  117. "id":5,
  118. "name":"Alyce Sawyer"
  119. },
  120. {
  121. "id":6,
  122. "name":"Rivas Owens"
  123. },
  124. {
  125. "id":7,
  126. "name":"Jan Petersen"
  127. }
  128. ],
  129. "greeting":"Hello, Butler Best! You have 8 unread messages.",
  130. "favoriteFruit":"banana"
  131. }
  132. ] 

表单json能达到这么长已经是很极端的情况了。因此这种方法绝对是够用的。

长表单内容加解密方法:

  1. function encrypt_data(publickey,data)
  2. {
  3. if(data.length>2691){return;}// length limit
  4. var crypt =newJSEncrypt();
  5. crypt.setPublicKey(publickey);
  6. crypt_res ="";
  7. for(var index=0; index <(data.length - data.length%117)/117+1; index++)
  8. {
  9. var subdata = data.substr(index *117,117);
  10. crypt_res += crypt.encrypt(subdata);
  11. }
  12. return crypt_res;
  13. }
  14. function decrypt_data(privatekey,data)
  15. {
  16. var crypt =newJSEncrypt();
  17. crypt.setPrivateKey(privatekey);
  18. datas=data.split('=');
  19. var decrypt_res="";
  20. datas.forEach(function(item)
  21. {
  22. if(item!=""){de_res += crypt.decrypt(item);}
  23. });
  24. return decrypt_res;
  25. }

更多详情见请继续阅读下一页的精彩内容:

  • 1
  • 2
  • 3
  • 下一页

相关内容

    暂无相关文章