一.RSA 算法简介
关于 RSA 加密算法可以参考:http://zh.wikipedia.org/wiki/RSA%E5%8A
%A0%E5%AF%86%E6%BC%94%E7%AE%97%E6%B3%95
大体是先生成两个大素数 p 和 q,再生成 e,e 和(p-1)*(q-1)互素。
取 p 和 q 的乘积:n=p*q 为公共模数。
再生成正整数 d,满足 d*e-1 可以被(p-1)*(q-1)整除。
这样 d 就为私钥,(e,n)为公钥,形成 rsa 的公私钥对。
其中 n 的二进制位称为该密钥长度,密钥越长越难破解,也就越安全。
二.填充算法
由于密钥长度有限,一次性加密的数据长度也有限,因此必须对明文进行分块加密,再合
并加密结果。
以 1024 位密钥为例,n 为 1024 位,即 128 个字节,则明文需要分块成每块长 128 个字
节,不足 128 位的使用特定格式的数据填充。
所以分块的算法称为填充算法,有不同的标准,如
NoPPadding、OAEPPadding、PKCS1Padding 等。
本文实现的是 PKCS1Padding 填充算法,规范文档是这个:http://
man.chinaunix.net/develop/rfc/RFC2313.txt
该算法规定的格式如下:
00 || BT || PS || 00 || D
其中 BT 可选择 01 和 02,01 表示私钥加密,02 表示公钥加密。如果 BT 是 01 则 PS 需
要使用 oxFF 填充,为 02 的话则需要使用随机非 0 填充。D 表示分割的明文块。
PS 的长度至少为 8 个字节,因此 D 至多只能为 128-8-2=117 个字节长。
三.C#实现
之所以要使用 C#实现是因为官方版本只实现了公钥加密且在明文中间增加了一些数字再
进行的加密,使用私钥解密出来后需要去除增加的数字。
而要实现私钥加密则只能自己实现了,这里使用到了一个大整数类:BigInteger。我是从这
里下载的:http://www.codeproject.com/Articles/2728/C-BigInteger-Class
C#里生成公私钥对可以使用如下代码:
RSACryptoServiceProvider key = new RSACryptoServiceProvider();
RSAParameters param = key.ExportParameters(true);
Console.WriteLine(Convert.ToBase64String(param.Modulus));
Console.WriteLine(Convert.ToBase64String(param.Exponent));
Console.WriteLine(Convert.ToBase64String(param.D));
其中 Modulus+Exponent 为公钥,D 为私钥,C#里是以 base64 格式保存的。
填充算法实现如下(blockLen 为模的字节数,这里为 128):
//填充
评论1
最新资源