RSA 算法细节|安全性考虑|Java应用

RSA是公钥密码学的经典算法之一,在1977年被Rivest, Shamir, Adleman三个人共同提出。
Ron Rivest http://theory.lcs.mit.edu/~rivest/
Adi Shamir http://www.wisdom.weizmann.ac.il/~shamir/
Len Adleman http://www.usc.edu/dept/molecular-science/

1. RSA算法基本参数

(1)是分组密码算法(区别于流密码算法)
(2)设计基于大整数分解难题
(3)明/密文分组以及公/私钥都被看作小于n的整数(n的大小通常为1024位二进制数)
(4)加/解密是模乘运算,假设某个明文分组是整数m( m<n ),则
加密: c=memodn
解密: m=cdmodn

2. 算法参数建立

step1:找素数,选取两个512bit的随机素数p,q,p!=q,计算模n和Euler函数 φ(n) (小于n且与n互素的正整数的个数)
step2:计算 npq φ(n)=(p1)(q1)
step3:找e、d满足 ed1modφ(n)
选取数e,用扩展Euclid算法求数d(e要求满足 gcdφ(n)e)=1;1<e<φ(n) )
step4:发布
公钥 ke=(e,n) ,私钥 kd=(d,n) ,d保密

3. RSA的安全考虑

RSA的安全性是基于大整数n的分解( n=pq ),公钥是(e,n)。从算法参数建立的过程,我们可以推出,如果敌手可以分解出 n=pq ,通过e与Euclid算法,则可求出私钥d,从而破解!所以,RSA的安全性即大整数分解难题。抵抗因子分解的一些考虑:
- n要尽量大,当前1024位应该是安全的
- p和q应该宽度接近,比如都约512位
- p-1和q-1应该都有大的素因子
- gcd(p1,q1) 应该比较小

4. 算法实例

(1)选p=7,q=17,则n=pq=119,且φ(n)=(p-1)(q-1)=6×16=96
(2)取e=5,则d=77 (5×77=385=4×96+1≡1 mod 96)
(3)则:公钥(5,119),私钥(77,119)
(4)加密明文分组 m=19,则 cmemodn=195mod119=66mod119
(5)解密密文分组 c=66,则 mcdmodn=6677mod11919mod119

5. 算法证明

欧拉定理:
If gcd(x,n)=1 , 则 xφ(n)=1modn .

加密: c=memodn –式1
解密: m=cdmodn –式2
将式1代入式2,现证明, m?=(memodn)dmodn
即:

m?=medmodn3

因为 ed1modφ(n) ,即 ed=kφ(n)+1 –式4
将式4代入式3,即证明:
m?=mkφ(n)modnm1modn5

因为m与n(n=pq)互素,即 mφ(n)=1modn –式6
将式6代入式5,即证明 m?=mmodn
得证!
备注:不考虑m=p or q,因为RSA分组是64位,一般n的选择1024、2048。。。,p与q的选择均不会太小,否则容易被破解。故而一般不会有m=p or q 的情况。

6. Java使用RSA进行签名、验签

//使用java提供的java.security.Signature类
//算法输入:SHA1withRSA | SHA256withRSA | SHA1withDSA等
//提供者:BC
public byte[] sign(PrivateKey privateKey, byte[] data) throws Exception{//签名
    byte[] result = null;
    Signature st = Signature.getInstance("SHA1withRSA","BC");
    st.initSign(privateKey);
    st.update(data);
    result = st.sign();
    return result;
}
public byte[] verify(PublicKey publicKey, byte[] signData, byte[] srcData) throws Exception{//验签
    Signature st = Signature.getInstance("SHA1withRSA","BC");
    st.initVerify(publicKey);
    st.update(srcData);
    return st.verify(signData);
}

6. keygin生成的公私钥格式

一般我们生成的公私钥,都是经过base64编码的。

-----BEGIN RSA PUBLIC KEY-----
BASE64 ENCODED DATA
-----END RSA PUBLIC KEY-----
//解码后:
RSAPublicKey ::= SEQUENCE {
    modulus           INTEGER,  -- n
    publicExponent    INTEGER   -- e
}

-----BEGIN RSA PRIVATE KEY-----
BASE64 ENCODED DATA
-----END RSA PRIVATE KEY-----
//解码后
RSAPrivateKey ::= SEQUENCE {
  version           Version,
  modulus           INTEGER,  -- n
  publicExponent    INTEGER,  -- e
  privateExponent   INTEGER,  -- d
  prime1            INTEGER,  -- p
  prime2            INTEGER,  -- q
  exponent1         INTEGER,  -- d mod (p-1)
  exponent2         INTEGER,  -- d mod (q-1)
  coefficient       INTEGER,  -- (inverse of q) mod p
  otherPrimeInfos   OtherPrimeInfos OPTIONAL
}

7. 其他

(1)公钥密码学的应用广泛,主要有实现数据保密性、数字签名、密钥交换三种。实现数据保密性时,便使用接收方的公钥加密(因为配对的私钥只有接收方拥有);实现数字签名时,使用发送方的私钥签名,别人通过你公布的公钥进行验签。
(2)因为个人公布的公钥并不可信,故而公钥的公布,一般通过证书中心(Certificate Authentication,CA)基于离线证书模式签发,当前X.509证书居多。CA是受信任的权威机构,有一对公钥私钥。
a) 每个用户自己产生一对公钥和私钥,并把公钥提交给CA申请证书。
b) CA以某种可靠的方式核对申请人的身份及其公钥,并用自己的私钥“签发”证书。
c) 证书主要内容:用户公钥,持有人和签发人的信息,用途,有效期间,签名等。X.509是公钥证书的格式标准(建议大家自己搜搜看x.509格式)。
d) 有了经CA签名保证的用户公钥,则可进行下一步的身份验证和交换会话密钥等。

转载请注明出处:http://blog.csdn.net/proteen/article/details/78826553

你可能感兴趣的:(密码学)