2016年5月20日 星期五

用 javascript 簡單寫 RSA 編解碼

1. 先安裝 nodejs 及 npm,
     sudo apt-get install nodejs  npm
2. 再用 npm 安裝 big-integer
     npm install big-integer

3. 用 openssl 產生 2048 bits 密鑰
     openssl genesa 2048 -out my.pem
     openssl rsa -text -in my.pem -out my.txt

4. 將 d, n, e 從  my.txt 擷取出來並利用 tr 及 bc 轉成 16 進位大整數的字串供程式編解碼使用
5. 使用 geditor 寫 java 程式:

// myrsa.js
var bigInt = require("big-integer");

sd="7E134469882EC2FA67B3142B96240043BDDCB946956773301736A81E45B5378CB6C11506C6BD2B4367E200B5D31C9F05C81220C43E9E7F405A3FB64C951F559B00F7F1586AE251E1EFE6793B43FBF2A283883C4843FF593ADD0273ED2786545AE42539911A9415AB41686E367A838E4CD4F6C6A2AC5B41B821651DD857DB29110DDAF7C2044B1227696E5F1EEC6FCAECD021DC4AD318937DAF58130B5594308D8EE7F6CCBB6CEE7B9B71CC2002FE342609E0717EB4FA67B61D55D11DFBABC6933FDA203400405E71CE87450968216A8C883187B562207216F213B12931F8D8AD4DF2361BC3FC404C8B088F33C0F66B7CAD2EDD1D796182DDC51153B34EBE7335";
sn="00CCCC68E135CDAD3A1BA300BBE2AEA65BD45F73EAD963A4C087E1E4CF60050F0E9077C59F62A98BB1DF20B371756C0DF310056FD678FF11011EB486C683B6F1F5C66A93C21F532F5E7C6EF2AABBCD681F5C013E1437C28268CCCEF01D83C4DC7E462AB06D103EBE5DDDB88982000D0D113F8520AB16679B2834517E6D1605733B6E7486E9629F9DD8E366D16A1E7D6AC836795C1889B74319816550ADB4EB8E5EAE805217E28E8FCA61496AE4DC7FB5E5C2A03E77FEAFCCFEFFB1A6C9EE96F8E239F2912665BEC90E3D960A997172E0C30C12ABEA96BBEAD59DD65506619099AA1829AB3494B6A8FE694296CB5AB08961DD11FAC39A80026CB39E6E287D1ABBC1";
se="10001";
sx="123456789";
n=bigInt(sn,16);
d=bigInt(sd,16);
e=bigInt(se,16);
x=bigInt(sx,16);
console.log("原文:"+x.toString(16));
m=x.modPow(e,n);
console.log("加密:"+m.toString(16));
z=m.modPow(d,n);
console.log("解密:"+z.toString(16));

6. 執行程式
        nodejs myrsa.js

7. 輸出結果:
原文:123456789
加密: 67a35bb7ed50b1583283cd2f2500ab6db74ba3da462e5ddda9089b76ae68c0e1e224ec5383ee6aaa9807014644dc5d3ed438b4f966f940f010ec7eb37dee8ccb297aae95ba20a22bc64638577127b2dd8225db736f41e740d90b8f7d915ebea5721b9f0dc4929f0f31f591009d9480eab98e654a98365b29a8ca0efeb1b812977689b3ac33926b11318f17082304ab57668d18148166fb182c76c02b1dd6a125685f55388ce407793b6ea804896a3e84566135ad06eabd6bd3b151b5954e48d38510f47e3893c2d939ed087ae64db2d68e30cccf834b38d74728b9a34bec20545885e65167282cb57a16a1358a3d3fed9b57a9ad3d966706ee8d295f303e50fd
解密:123456789

8. 可看出最後的輸出等於原文 "123456789"

big-integer 大數運算的使用用法參考網址: https://www.npmjs.com/package/big-integer


後記:
1. 將明文(text stream)轉成16進制字串 (HEX string), 僅支援英文字母, 中文有些問題要解決
       text="IJKSDFJKEDFKDF";
       sx=""; for(i=0;i<text.length;i++) sx+=text.charCodeAt(i).toString(16)
2. 將16進制字串 (HEX string)轉回明文(text stream), 僅支援英文字母,中文有些問題要解決
        zx=sx;
mx=""; for(i=0;i<zx.length/2;i++)    mx +=  String.fromCharCode(  parseInt(zx.substr(2*i,2),16) );









沒有留言: