1、RSA 公钥和私钥的组成。以及加密和解密的公式:
2、模指数运算:
先做指数运算,再做模运算。如 5^3 mod 7 = 125 mod 7 = 6
3、RSA加密算法流程:
-
- 选择一对不同的、而且足够大的素数 p 和 q
- 计算 n = p * q
- 计算欧拉函数 f(n) = (p-1) * (q-1),p 和 q 须要保密
- 寻找与 f(n) 互质的数 e。而且 1 < e < f(n)
- 计算 d,使得 d * e ≡ 1 mod f(n)
- 公钥 KU = (e , n) 私钥 KR = (d , n)
- 加密时,将明文变换成 0 ~ n-1 的一个整数 M。明文较长能够切割。设密文为 C,则加密过程是:C ≡ M^e mod n
- 解密时,M ≡ C^d mod n
当中 ≡ 表示同余,就是符号两边模运算结果同样。由于符号右边结果恒为 1所以要找到符合条件的 d 使得 d * e mod f(n) = 1
4、OpenSSL中RSA加密解密实现
(1)BN_MONT_CTX /* Used for montgomery multiplication */ struct bn_mont_ctx_st { int ri; /* number of bits in R */ BIGNUM RR; /* used to convert to montgomery form */ BIGNUM N; /* The modulus */ BIGNUM Ni; /* R*(1/R mod N) - N*Ni = 1 * (Ni is only stored for bignum algorithm) */ BN_ULONG n0[2]; /* least significant word(s) of Ni; (type changed with 0.9.9, was "BN_ULONG n0;" before) */ int flags; };
(2)BIGNUM
struct bignum_st
{
BN_ULONG *d; /* Pointer to an array of 'BN_BITS2' bit chunks. */
int top; /* Index of last used d +1. */
/* The next are internal book keeping for bn_expand. */
int dmax; /* Size of the d array. */
int neg; /* one if the number is negative */
int flags;
};
d:BN_ULONG (应系统而异,win32 下为4 个字节) 数组指针首地址,大数就存放在这里面,只是是倒放的。比方。用户要存放的大数为
12345678000(通过BN_bin2bn 放入)。则d 的内容例如以下: 0x30 0x30 0x30 0x38 0x37 0x36 0x35 0x34 0x33 0x32 0x31 ;(注意这里是以ASCII码存放的。他是字符转 bignum )