Good,True and Beautiful

Good Good Study, Day Day Up

导航

RSA

1 原理

大整数分解困难, 因而暴露一个大整数是安全的。

1.1 过程

加密 M -> c, ( 公钥 N, e)
\(c \equiv M^e \quad (mod \; N)\)
解密 c -> M, (私钥 N, d)
\(M \equiv c^d \quad (mod \; N)\)

1.2 公私钥生成

  1. 随机生成两个素数 p,q
  2. 计算 N=pq
  3. 计算 欧拉数 \(\psi(N)=(p-1)(q-1)\)
  4. 选取指数e, 满足 \(e \in (1,\psi(n)) 且与\psi(n)互质.实践中一般选e为一个素数, 如65537\)
  5. 计算e的乘法逆元d,满足 \(ed \equiv 1 \quad (mod\; \psi(n) )\)
  6. 公钥 N和e, 私钥 N和d

1.3 解密原理

根据一般化的欧拉定理,
\(当 x \equiv y \quad (mod \; \psi(n))时, a^x \equiv a^y \quad (mod \; n)\)
因为: \(ed \equiv 1 \quad (mod\; \psi(n) )\)
故有:\(M^{ed} \equiv M \quad (\mod \, N)\)
又:\(c \equiv M^e \quad (\mod \, N)\)
故根据同余指数性质:
\(c^d \equiv M^{ed} \equiv M \quad (mod \; n)\)

2 代码

RSA = {}
RSA.math = {}
RSA.key = {"N":0,"E":0,"D":0} 

RSA.math.powmod = function(a,e,m){
    if( m == null) return Math.pow(a,e)
    var ma = a % m, b = ma,i=1;
    for(;i<e;i++){
        b = b * ma % m
    }
    return b
}

RSA.math.rand = function(s,e){
    if( e == null ){
        e = s ; s = 0;
    }
    e = Math.max(s,e)
    s = Math.min(s,e)
    var r = Math.random(),d=e-s
    return parseInt( d*r ) + s
}

RSA.math.prime = function(s){
    if( s % 2 ==0) s += 1;
    while( !this.isPrime(s)) s+=2;
    return s;
}

RSA.math.isPrime = function(a){
    if( a % 2 ==0) return 0
    var e = parseInt(Math.sqrt(a)) +1,i=3;
    while( i<e && a%i ) i+=2;
    return i>=e
}

RSA.math.gcd = function(a,b){
    if(a==0) {return b } else { while(b){ if(a>b) a=a-b; else b = b-a; }return a}
}

RSA.math.coprime = function(a){
    for(var i=3;i<a;i++){
        if( this.gcd(a,i) === 1) break;
    }
    return i<a?i:NaN
}

RSA.gen = function(a,b){
    a = this.math.prime( a || this.math.rand(10,100) )
    b = this.math.prime( b || this.math.rand(10,100) )
    var npq = (a-1)*(b-1),e = this.math.coprime(npq)
    if( String(e) == 'NaN' ){
        return console.info('error:cannot find e')
    }
    var limit = Number.MAX_VALUE / 100 / Math.max(a,b)
    for(var i=e+1;i<limit;i++){
        if( i*e % npq === 1) break;
    }
    if( i >=limit ){
        return console.info('error:cannot find d')
    }
    var d = i
    this.key.N = a*b
    this.key.E = e
    this.key.D = d
    this.key.data = {p:a,q:b,key:this.key}
    return this
}

RSA.encode = function(m){
    return this.math.powmod(m,this.key.E,this.key.N)
}

RSA.decode = function(e){
    return this.math.powmod(e,this.key.D,this.key.N)
}

posted on 2024-01-23 12:29  Simple Love  阅读(21)  评论(0编辑  收藏  举报