rsa 公 填充模式的_RSA默认填充方式说明

rsa加密--选择padding模式需要注意的问题。。。

RSA加密常用的填充方式有下面3种:

1.RSA_PKCS1_PADDING 填充模式,最常用的模式

要求:

输入:必须 比 RSA 钥模长(modulus) 短至少11个字节, 也就是 RSA_size(rsa) – 11

如果输入的明文过长,必须切割, 然后填充

输出:和modulus一样长

根据这个要求,对于512bit的密钥, block length = 512/8 – 11 = 53 字节

2.RSA_PKCS1_OAEP_PADDING

输入:RSA_size(rsa) – 41

输出:和modulus一样长

3.for RSA_NO_PADDING  不填充

输入:可以和RSA钥模长一样长,如果输入的明文过长,必须切割, 然后填充

输出:和modulus一样长

跟DES,AES一样,RSA也是一个块加密算法( block cipher algorithm),总是在一个固定长度的块上进行操作。但跟AES等不同的是, block length是跟key length有关的。每次RSA加密的明文的长度是受RSA填充模式限制的,但是RSA每次加密的块长度就是key length。

需要注意:

在BouncyCastle实现RSA的PKCS1V1.5模式中,如果是公钥加密信息(forEncryption=true),密钥长度为1024位,那么输出的密文块长度为128个字节,输入的明文块长度为127-10,即输入的明文块最大是117位,如果输入的明文块小于117位,比如输入的明文块长度为64位,那么会对这个明文块进行补位,在明文块前添加一位的0x02字节(代表公钥加密)然后后面的52位为随机的字节,在补位的最后一位,{即52(117-64-1),从零开始的},添加一位的字节0x00,在补位的后面添加实际的明文块。

这样做的目的就是使得明文块转化成与module差不多的大整数。

如果是私钥加密(forPrivateKey=true),密钥长度为1024位,那么输出 的密文块长度也是128字节,输入的明文块的长度为127-10,即输入的明文块最大是117位,如果输入的明文块小于117位,比如输入的明文块长度为64位,那么对这个明文块进行补位,在明文块千添加一位的0x01字节(代表私钥加密),然后在后面的52位为字节0xff,在最后一位{即52(117-64-1),从零开始),添加一位的字节0x00,在补位的后面添加时间的明文块。

RSA算法在运算时需要将数据填充至分组长度(与RSA密钥模长相等)。

PAD方式分下面两种:

EM = 0x00 || 0x01 || PS || 0x00 || T

PS : pad with 0xFF, length : Len(EM) - 3 - Len(T)

EM = 0x00 || 0x02 || PS || 0x00 || M

PS : pad with random data, length : Len(EM) - 3 - Len(M)

填充串PS的长度最少为8个字节,这是RSA操作的一种安全措施。

所以RSA签名的数据长度不能超过分组长度-11字节。

这个在http://tools.ietf.org/html/rfc2313中的“8.1 Encryption-block formatting”3可以找到。

3.RSA_PKCS1_OAEP_PADDING填充模式没有使用过, 他是PKCS#1推出的新的填充方式,安全性是最高的,和前面RSA_PKCS1_PADDING的区别就是加密前的编码方式不一样。

http://tools.ietf.org/html/rfc2313 这里面有一些关于RSA加密PKCS#1标准的有关介绍,感兴趣的同学

可以去看一下。。。

int RSA_sign(int type, const unsigned char *m, unsigned int m_len, unsigned char *sigret, unsigned int *siglen, RSA *rsa);

会根据type是SHA1还是MD5,给m加header,sha1 header = 15 bytes, md5 head = 18 bytes

我们把RSA_sign签名后的数据进行解密,用int RSA_public_decrypt(int flen, unsigned char *from, unsigned char *to, RSA *rsa, int padding);函数,发现解密后的数据为:

$ ./a.exe (我写的一个验证程序 rsa-sysssl.c)

sha1 header: (15 bytes) 3021300906052b0e03021a05000414

sha1 data: 395e4981d467d1bd120dfb708ed4e3869c34bc04

input string = aaabbbccc

sha1 header: (15 bytes) 3021300906052b0e03021a05000414

sha1 data: 299fbb21cb784c917664fe027deb52d1ee8b24ea

input string = asdfajkhsdf

这就证实了我们上面RSA_sign会给数据加header的做法,其实header的含义是这样:

/*

* See:

* http://www.rsasecurity.com/rsalabs/pkcs/pkcs-1/

* ftp://ftp.rsasecurity.com/pub/pkcs/pkcs-1/pkcs-1v2-1.asn

*/

/*

* id-sha1 OBJECT IDENTIFIER ::= { iso(1) identified-organization(3)

* oiw(14) secsig(3) algorithms(2) 26 }

*/

static const u_char id_sha1[] = {

0x30, 0x21, /* type Sequence, length 0x21 (33) */

0x30, 0x09, /* type Sequence, length 0x09 */

0x06, 0x05, /* type OID, length 0x05 */

0x2b, 0x0e, 0x03, 0x02, 0x1a, /* id-sha1 OID */

0x05, 0x00, /* NULL */

0x04, 0x14 /* Octet string, length 0x14 (20), followed by sha1 hash */

};

/*

* id-md5 OBJECT IDENTIFIER ::= { iso(1) member-body(2) us(840)

* rsadsi(113549) digestAlgorithm(2) 5 }

*/

static const u_char id_md5[] = {

0x30, 0x20, /* type Sequence, length 0x20 (32) */

0x30, 0x0c, /* type Sequence, length 0x09 */

0x06, 0x08, /* type OID, length 0x05 */

0x2a, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x02, 0x05, /* id-md5 */

0x05, 0x00, /* NULL */

0x04, 0x10 /* Octet string, length 0x10 (16), followed by md5 hash */

};

你可能感兴趣的:(rsa,公,填充模式的)