source: Dev/trunk/src/client/dojox/encoding/crypto/RSAKey-ext.js @ 531

Last change on this file since 531 was 483, checked in by hendrikvanantwerpen, 11 years ago

Added Dojo 1.9.3 release.

File size: 3.3 KB
Line 
1define([
2        "dojo/_base/kernel", // dojo.experimental
3        "dojo/_base/lang", // dojo.extend
4        "./RSAKey",
5        "../../math/BigInteger-ext"
6], function(kernel, lang, RSAKey, BigInteger) {
7
8        kernel.experimental("dojox.encoding.crypto.RSAKey-ext");
9
10        // Undo PKCS#1 (type 2, random) padding and, if valid, return the plaintext
11        function pkcs1unpad2(d, n){
12                var b = d.toByteArray();
13                for(var i = 0, len = b.length; i < len && !b[i]; ++i);
14                if(b.length - i !== n - 1 || b[i] !== 2){
15                        return null;
16                }
17                for(++i; b[i];){
18                        if(++i >= len){
19                                return null;
20                        }
21                }
22                var ret = "";
23                while(++i < len){
24                        ret += String.fromCharCode(b[i]);
25                }
26                return ret;
27        }
28
29        lang.extend(RSAKey, {
30                setPrivate: function(N, E, D){
31                        // summary:
32                        //              Set the private key fields N, e, d and CRT params from hex strings
33                        if(N && E && N.length && E.length){
34                                this.n = new BigInteger(N, 16);
35                                this.e = parseInt(E, 16);
36                                this.d = new BigInteger(D, 16);
37                        }else{
38                                throw new Error("Invalid RSA private key");
39                        }
40                },
41                setPrivateEx: function(N, E, D, P, Q, DP, DQ, C) {
42                        // summary:
43                        //              Set the private key fields N, e, d and CRT params from hex strings
44                        if(N && E && N.length && E.length){
45                                this.n = new BigInteger(N, 16);
46                                this.e = parseInt(E, 16);
47                                this.d = new BigInteger(D, 16);
48                                this.p = new BigInteger(P, 16);
49                                this.q = new BigInteger(Q, 16);
50                                this.dmp1 = new BigInteger(DP, 16);
51                                this.dmq1 = new BigInteger(DQ, 16);
52                                this.coeff = new BigInteger(C, 16);
53                        }else{
54                                throw new Error("Invalid RSA private key");
55                        }
56                },
57                generate: function(B, E){
58                        // summary:
59                        //              Generate a new random private key B bits long, using public expt E
60                        var rng = this.rngf(), qs = B >> 1;
61                        this.e = parseInt(E, 16);
62                        var ee = new BigInteger(E, 16);
63                        for(;;) {
64                                for(;;) {
65                                        this.p = new BigInteger(B - qs, 1, rng);
66                                        if(!this.p.subtract(BigInteger.ONE).gcd(ee).compareTo(BigInteger.ONE) && this.p.isProbablePrime(10)){
67                                                break;
68                                        }
69                                }
70                                for(;;) {
71                                        this.q = new BigInteger(qs, 1, rng);
72                                        if(!this.q.subtract(BigInteger.ONE).gcd(ee).compareTo(BigInteger.ONE) && this.q.isProbablePrime(10)){
73                                                break;
74                                        }
75                                }
76                                if(this.p.compareTo(this.q) <= 0) {
77                                        var t = this.p;
78                                        this.p = this.q;
79                                        this.q = t;
80                                }
81                                var p1 = this.p.subtract(BigInteger.ONE);
82                                var q1 = this.q.subtract(BigInteger.ONE);
83                                var phi = p1.multiply(q1);
84                                if(!phi.gcd(ee).compareTo(BigInteger.ONE)) {
85                                        this.n = this.p.multiply(this.q);
86                                        this.d = ee.modInverse(phi);
87                                        this.dmp1 = this.d.mod(p1);
88                                        this.dmq1 = this.d.mod(q1);
89                                        this.coeff = this.q.modInverse(this.p);
90                                        break;
91                                }
92                        }
93                        rng.destroy();
94                },
95
96                decrypt: function(ctext){
97                        // summary:
98                        //              Return the PKCS#1 RSA decryption of "ctext".
99                        // ctext: String
100                        //              an even-length hex string
101                        // returns:
102                        //              a plain string.
103                        var c = new BigInteger(ctext, 16), m;
104                        if(!this.p || !this.q){
105                                m = c.modPow(this.d, this.n);
106                        }else{
107                                // TODO: re-calculate any missing CRT params
108                                var cp = c.mod(this.p).modPow(this.dmp1, this.p),
109                                        cq = c.mod(this.q).modPow(this.dmq1, this.q);
110                                while(cp.compareTo(cq) < 0){
111                                        cp = cp.add(this.p);
112                                }
113                                m = cp.subtract(cq).multiply(this.coeff).mod(this.p).multiply(this.q).add(cq);
114                        }
115                        if(!m){
116                                return null;
117                        }
118                        return pkcs1unpad2(m, (this.n.bitLength() + 7) >> 3);
119                }
120        });
121       
122        return RSAKey;
123});
Note: See TracBrowser for help on using the repository browser.