问题描述
我能够使用RSA加密算法在Knockoutjs中加密字符串
我想在客户端(在剔除js中)解密相同的消息,请给我一个有关如何调用解密函数的想法。
define(['myDocs/rsa-encrypt'],function (RSA) {
var self = this;
var rsa = new RSA();
var plainText = "Hi there,Good morning!";
var modulus = "009FF824A85E7EE8B5F41EF98DA25CF73BB34EC0E9EE3710C175187AD5DAFE82AB0F216703B2355E20979D693CBB50942ED2E80F59AF40F30F0FFBE78DDA2C1660CDEC8FC827EBA0A829F0172279F07402CDAB4343399FEA557BBAA88569E3476DFB66AA5DD02512E747DFD797CCA153E0E3A4312460BDF9210DFAA866130437AF";
var publicExponent = "010001";
self.encrypt = function (plainText) {
rsa.setPublic(modulus,publicExponent);
var res = rsa.prototype.encrypt_b64(plainText);
console.log(res);
});
self.decrypt = function () {
//need to understand this logic
});
});
//rsa-encrypt file details Details :
define([],function() {
// convert a (hex) string to a bignum object
function parseBigInt(str,r) {
return new BigInteger(str,r);
}
function linebrk(s,n) {
var ret = "";
var i = 0;
while(i + n < s.length) {
ret += s.substring(i,i+n) + "\n";
i += n;
}
return ret + s.substring(i,s.length);
}
function byte2Hex(b) {
if(b < 0x10)
return "0" + b.toString(16);
else
return b.toString(16);
}
// PKCS#1 (type 2,random) pad input string s to n bytes,and return a bigint
function pkcs1pad2(s,n) {
if(n < s.length + 11) { // Todo: fix for utf-8
alert("Message too long for RSA");
return null;
}
var ba = new Array();
var i = s.length - 1;
while(i >= 0 && n > 0) {
var c = s.charCodeAt(i--);
if(c < 128) { // encode using utf-8
ba[--n] = c;
}
else if((c > 127) && (c < 2048)) {
ba[--n] = (c & 63) | 128;
ba[--n] = (c >> 6) | 192;
}
else {
ba[--n] = (c & 63) | 128;
ba[--n] = ((c >> 6) & 63) | 128;
ba[--n] = (c >> 12) | 224;
}
}
ba[--n] = 0;
var rng = new SecureRandom();
var x = new Array();
while(n > 2) { // random non-zero pad
x[0] = 0;
while(x[0] == 0) rng.nextBytes(x);
ba[--n] = x[0];
}
ba[--n] = 2;
ba[--n] = 0;
return new BigInteger(ba);
}
// "empty" RSA key constructor
function RSAKey() {
this.n = null;
this.e = 0;
this.d = null;
this.p = null;
this.q = null;
this.dmp1 = null;
this.dmq1 = null;
this.coeff = null;
}
// Set the public key fields N and e from hex strings
function RSASetPublic(N,E) {
if(N != null && E != null && N.length > 0 && E.length > 0) {
this.n = parseBigInt(N,16);
this.e = parseInt(E,16);
}
else
alert("Invalid RSA public key");
}
// Perform raw public operation on "x": return x^e (mod n)
function RSADoPublic(x) {
return x.modPowInt(this.e,this.n);
}
// Return the PKCS#1 RSA encryption of "text" as an even-length hex string
function RSAEncrypt(text) {
var m = pkcs1pad2(text,(this.n.bitLength()+7)>>3);
if(m == null) return null;
var c = this.doPublic(m);
if(c == null) return null;
var h = c.toString(16);
if((h.length & 1) == 0) return h; else return "0" + h;
}
// Return the PKCS#1 RSA encryption of "text" as a Base64-encoded string
//function RSAEncryptB64(text) {
// var h = this.encrypt(text);
// if(h) return hex2b64(h); else return null;
//}
// protected
RSAKey.prototype.doPublic = RSADoPublic;
// public
RSAKey.prototype.setPublic = RSASetPublic;
RSAKey.prototype.encrypt = RSAEncrypt;
RSAKey.prototype.encrypt_b64 = RSAEncryptB64;
return RSAKey;
});
可用于解密的代码:
define([],function() {
var rSeed=[],Rs=[];
var Sr,Rsl,Rbits,Rbits2;
var Rx=0,Ry=0;
// javascript's random 0 .. n
function r(n)
{
return Math.floor(Math.random()*n);
}
function ror(a,n)
{
n&=7;
return n?((a>>n)|((a<<(8-n))&255)):a;
}
// seed the random number generator with entropy in s
function seed(s)
{
var n=0,nn=0;
var x,y,t;
while(n < s.length)
{
while(n<s.length && s.charCodeAt(n)<=32) n++;
if(n < s.length) rSeed[nn]=parseInt("0x"+s.substr(n,2));
n+=3; nn++;
}
Rsl=rSeed.length;
Sr=r(256);
Rbits=0;
if(Rs.length==0)
{
for(x=0; x<256; x++) Rs[x]=x;
}
y=0;
for(x=0; x<256; x++)
{
y=(rSeed[x] + s[x] + y) % 256;
t=s[x]; s[x]=s[y]; s[y]=t;
}
Rx=Ry=0;
alert("Random seed updated. Seed size is: "+Rsl);
}
// generate a random number 0 .. 255 uses entropy from seed
function rc()
{
var t;
// this first bit is basically RC4
Rx=++Rx & 255;
Ry=(Rs[Rx] + Ry) & 255;
t=Rs[Rx]; Rs[Rx]=Rs[Ry]; Rs[Ry]=t;
Sr^= Rs[(Rs[Rx] + Rs[Ry]) & 255];
// xor with javascripts rand,just in case there's good entropy there
Sr^= r(256);
Sr^= ror(rSeed[r(Rsl)],r(8));
Sr^= ror(rSeed[r(Rsl)],r(8));
return Sr;
}
// random number between 0 .. n -- based on repeated calls to rc
function rand(n)
{
if(n==2)
{
if(!Rbits)
{
Rbits=8;
Rbits2=rc(256);
}
Rbits--;
var r=Rbits2 & 1;
Rbits2>>=1;
return r;
}
var m=1;
r=0;
while (n>m && m > 0)
{
m<<=8; r=(r<<8) |rc();
}
if(r<0) r ^= 0x80000000;
return r % n;
}
// ------------------------------------------------------------
// functions for generating keys
// ------------------------------------------------------------
function beq(a,b) // returns 1 if a == b
{
if(a.length != b.length) return 0;
for(var n=a.length-1; n>=0; n--)
{
if(a[n] != b[n]) return 0;
}
return 1;
}
function blshift(a,b) // binary left shift b bits
{
var n,c=0;
var r=new Array(a.length);
for(n=0; n<a.length; n++)
{
c|= (a[n]<<b);
r[n]= c & bm;
c>>=bs;
}
if(c) r[n]=c;
return r;
}
function brshift(a) // unsigned binary right shift 1 bit
{
var c=0,n,cc;
var r=new Array(a.length);
for(n=a.length-1; n>=0; n--)
{
c<<=bs;
cc=a[n];
r[n]=(cc | c)>>1;
c=cc & 1;
}
n=r.length;
if(r[n-1]) return r;
while(n > 1 && r[n-1]==0) n--;
return r.slice(0,n);
}
function bgcd(uu,vv) // return greatest common divisor
{
// algorythm from http://algo.inria.fr/banderier/Seminar/Vallee/index.html
var d,t,v=vv.concat(),u=uu.concat();
for(;;)
{
d=bsub(v,u);
if(beq(d,[0])) return u;
if(d.length)
{
while((d[0] & 1) ==0) d=brshift(d); // v=(v-u)/2^val2(v-u)
v=d;
}
else
{
t=v; v=u; u=t; // swap u and v
}
}
}
function rnum(bits)
{
var n,b=1,c=0;
var a=[];
if(bits==0) bits=1;
for(n=bits; n>0; n--)
{
if(rand(2)) a[c]|=b;
b<<=1;
if(b==bx2)
{
b=1;
c++;
}
}
return a;
}
var Primes=[3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,59,61,67,71,73,79,83,89,97,101,103,107,109,113,127,131,137,139,149,151,157,163,167,173,179,181,191,193,197,199,211,223,227,229,233,239,241,251,257,263,269,271,277,281,283,293,307,311,313,317,331,337,347,349,353,359,367,373,379,383,389,397,401,409,419,421,431,433,439,443,449,457,461,463,467,479,487,491,499,503,509,521,523,541,547,557,563,569,571,577,587,593,599,601,607,613,617,619,631,641,643,647,653,659,661,673,677,683,691,701,709,719,727,733,739,743,751,757,761,769,773,787,797,809,811,821,823,827,829,839,853,857,859,863,877,881,883,887,907,911,919,929,937,941,947,953,967,971,977,983,991,997,1009,1013,1019,1021];
var sieveSize=4000;
var sieve0=-1* sieveSize;
var sieve=[];
var lastPrime=0;
function nextPrime(p) // returns the next prime > p
{
var n;
if(p == Primes[lastPrime] && lastPrime <Primes.length-1)
{
return Primes[++lastPrime];
}
if(p<Primes[Primes.length-1])
{
for(n=Primes.length-2; n>0; n--)
{
if(Primes[n] <= p)
{
lastPrime=n+1;
return Primes[n+1];
}
}
}
// use sieve and find the next one
var pp,m;
// start with p
p++; if((p & 1)==0) p++;
for(;;)
{
// new sieve if p is outside of this sieve's range
if(p-sieve0 > sieveSize || p < sieve0)
{
// start new sieve
for(n=sieveSize-1; n>=0; n--) sieve[n]=0;
sieve0=p;
primes=Primes.concat();
}
// next p if sieve hit
if(sieve[p-sieve0]==0)
{
// sieve miss
// update sieve if p divisable
// find a prime divisor
for(n=0; n<primes.length; n++)
{
if((pp=primes[n]) && p % pp ==0)
{
for(m=p-sieve0; m<sieveSize; m+=pp) sieve[m]=pp;
p+=2;
primes[n]=0;
break;
}
}
if(n >= primes.length)
{
// possible prime
return p;
}
}
else
{
p+=2;
}
}
}
function divisable(n,max) // return a factor if n is divisable by a prime less than max,else return 0
{
if((n[0] & 1) == 0) return 2;
for(c=0; c<Primes.length; c++)
{
if(Primes[c] >= max) return 0;
if(simplemod(n,Primes[c])==0) return Primes[c];
}
c=Primes[Primes.length-1];
for(;;)
{
c=nextPrime(c);
if(c >= max) return 0;
if(simplemod(n,c)==0) return c;
}
}
function bPowOf2(pow) // return a bigint
{
var r=[],m=Math.floor(pow/bs);
for(n=m-1; n>=0; n--) r[n]=0;
r[m]=1<<(pow % bs);
return r;
}
function mpp(bits) // returns a Maurer Provable Prime,see HAC chap 4 (c) CRC press
{
if(bits < 10) return [Primes[rand(Primes.length)]];
if(bits <=20) return [nextPrime(rand(1<<bits))];
var c=10,m=20,B=bits*bits/c,r,q,I,R,a,b,d,R2,nMinus1;
if(bits > m*2)
{
for(;;)
{
r=Math.pow(2,Math.random()-1);
if(bits - r * bits > m) break;
}
}
else
{
r=0.5
}
q=mpp(Math.floor(r*bits)+1);
I=bPowOf2(bits-2);
I=bdiv(I,q).q;
Il=I.length;
for(;;)
{
// generate R => I < R < 2I
R=[];
for(n=0; n<Il; n++) R[n]=rand(bx2);
R[Il-1] %= I[Il-1];
R=bmod(R,I);
if(!R[0]) R[0]|=1; // must be greater or equal to 1
R=badd(R,I);
n=blshift(bmul(R,q),1); // 2Rq+1
n[0]|=1;
if(!divisable(n,B))
{
a=rnum(bits-1);
a[0]|=2; // must be greater than 2
nMinus1=bsub(n,[1]);
var x=bmodexp(a,nMinus1,n);
if(beq(x,[1]))
{
R2=blshift(R,1);
b=bsub(bmodexp(a,n),[1]);
d=bgcd(b,n);
if(beq(d,[1])) return n;
}
}
}
}
// -------------------------------------------------
function sub2(a,b)
{
var r=bsub(a,b);
if(r.length==0)
{
this.a=bsub(b,a);
this.sign=1;
}
else
{
this.a=r;
this.sign=0;
}
return this;
}
function signedsub(a,b)
{
if(a.sign)
{
if(b.sign) return sub2(b,a);
else
{
this.a=badd(a,b);
this.sign=1;
}
}
else
{
if(b.sign)
{
this.a=badd(a,b);
this.sign=0;
}
else return sub2(a,b);
}
return this;
}
// from Bryan Olson <[email protected]>
function modinverse(x,n) // returns x^-1 mod n
{
var y=n.concat(),bq,a=[1],b=[0],ts;
a.sign=0; b.sign=0;
while(y.length > 1 || y[0])
{
t=y.concat();
r=bdiv(x,y);
y=r.mod;
q=r.q;
x=t;
t=b.concat(); ts=b.sign;
bq=bmul(b,q);
bq.sign=b.sign;
r=signedsub(a,bq);
b=r.a; b.sign=r.sign;
a=t; a.sign=ts;
}
if(x.length != 1 || x[0] != 1) return [0]; // No inverse; GCD is x
if(a.sign)
{
a=bsub(n,a);
}
return a;
}
// -------------------------------------------------
// function to generate keys
var rsa_p,rsa_q,rsa_e,rsa_d,rsa_pq,rsa_u;
function rsaKeys(bits)
{
var c,p1q1;
bits=parseInt(bits);
rsa_q=mpp(bits);
rsa_p=mpp(bits);
p1q1=bmul(bsub(rsa_p,[1]),bsub(rsa_q,[1]));
for(c=5; c<Primes.length; c++)
{
rsa_e=[Primes[c]];
rsa_d=modinverse(rsa_e,p1q1);
if(rsa_d.length != 1 || rsa_d[0]!=0) break;
}
rsa_pq=bmul(rsa_p,rsa_q);
rsa_u=modinverse(rsa_p,rsa_q);
return;
}
});
解决方法
暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!
如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。
小编邮箱:dio#foxmail.com (将#修改为@)