C++ RSA加密解密签字通信系统源码
如需安装运行环境或远程调试,可加扣905733049, 或扣2945218359由专业技术人员远程协助!
运行结果如下:
主要代码:
#include "stdafx.h"
RSA* getPrivateKey(char* in_szKeyPath)
{
FILE* fp = NULL;
char szKeyPath[1024];
RSA* priRsa = NULL, * pubRsa = NULL, * pOut = NULL;
memset(szKeyPath, 0, sizeof(szKeyPath));
if (256 < strlen(in_szKeyPath))
strncpy_s(szKeyPath, in_szKeyPath, 256);
else
strncpy, in_szKeyPath, strlen(in_szKeyPath));
printf("密钥文件路径[%s]", szKeyPath);
/* 打开密钥文件 */
errno_t eErr = fopen_s(&fp, szKeyPath, "rb");
if (eErr != 0)
{
printf("打开密钥文件[%s]出错", szKeyPath);
return NULL;
}
/* 获取私密钥 */
if (NULL == (priRsa = PEM_read_RSAPrivate(fp, &priRsa, NULL, NULL)))
{
printf("读出私钥内容出错\n");
fclose(fp);
return NULL;
}
fclose(fp);
printf("提取私钥\n");
pOut = priRsa;
return pOut;
}
RSA* getPublicKey(char* in_szKeyPath)
{
FILE* fp = NULL;
char szKeyPath[1024];
RSA* priRsa = NULL, * pubRsa = NULL, * pOut = NULL;
memset(szKeyPath, 0, sizeof(szKeyPath));
if (256 < strlen(in_szKeyPath))
strncpy_s(szKeyPath, in_szKeyPath, 256);
else
strncpy_s(szKeyPath, in_szKeyPath, strlen(in_szKeyPath));
printf("密钥文件路径[%s]", szKeyPath);
/* 打开密钥文件 */
errno_t eErr = fopen_s(&fp, szKeyPath, "rb");
if (eErr != 0)
{
printf("打开密钥文件[%s]出错", szKeyPath);
return NULL;
}
/* 获取公密钥 */
if (NULL == (priRsa = PEM_read_RSA_PUBKEY(fp, &priRsa,NULL)))
{
printf("读出私钥内容出错\n");
fclose(fp);
return NULL;
}
fclose(fp);
printf("提取公钥\n");
pOut = priRsa;
return pOut;
}
主要算法说明:
RSA算法全过程
我们已经差不多把RSA算法的全过程都解释了一遍,现在来浏览一下真正的RSA算法全过程吧。
密钥生成
选择大素数p与q,计算n = p q n=pqn=pq,φ ( n ) = ( p − 1 ) ( q − 1 ) \varphi(n)=(p-1)(q-1)φ(n)=(p−1)(q−1),然后丢弃p和q,不保留。
在1 < e < φ ( n ) 1<e<\varphi(n)1<e<φ(n)的范围内选择整数公钥e,使得g c d ( e , φ ( n ) ) = 1 gcd(e,\varphi(n))=1gcd(e,φ(n))=1(若e ee和φ ( n ) \varphi(n)φ(n)不互质,则不存在私钥d dd,这点上面已经证明过了)。
计算私钥d,d = e − 1 m o d φ ( n ) d=e^{-1}\mod \varphi(n)d=e
−1
modφ(n)。
加密过程
发送方获得公钥对{e,n}
把明文m mm分解为小于n的若干块
计算密文C = m e m o d n C=m^e\mod nC=m
e
modn
解密过程
接收方提前内置密钥对{d,n}
对密文解密m = C d m o d n m=C^d\mod nm=C
d
modn
尾声:RSA算法正确性证明
回到我们最开始先忽略的那一个问题,既然欧拉定理要求底数a与模n互质,当明文a与模n不互质的时候,还能够完成加密并解密的任务吗?先给出结论,结论是只要a不是模n的倍数,RSA算法就是正确的。既然我们要求了a < n a<na<n,那么a是n的倍数的可能性不复存在。
以下是证明:
设 n = p q , a 是 某 一 个 整 数 、 g c d ( a , n ) ≠ 1 且 n 不 能 被 a 整 除 , 试 证 明 a ≡ a k φ ( n ) + 1 ( m o d n ) 设n=pq,a是某一个整数、gcd(a,n)\neq 1 且n不能被a整除,试证明a\equiv a^{k\varphi(n)+1}(\mod n)
设n=pq,a是某一个整数、gcd(a,n)
=1且n不能被a整除,试证明a≡a
kφ(n)+1
(modn)
若 a 与 n 不 互 质 , 必 有 p ∣ a ( p 能 被 a 整 除 ) 或 者 q ∣ a 。 设 p ∣ a 成 立 , 必 有 g c d ( q , a ) = 1 , 否 则 n ∣ a , 不 符 合 题 设 条 件 。 同 理 设 q ∣ a 成 立 也 是 一 样 的 情 况 , 不 失 一 般 性 , 设 p ∣ a 成 立 。 由 欧 拉 定 理 和 φ ( n ) = ( p − 1 ) ( q − 1 ) 得 到 : a φ ( n ) ≡ 1 ( m o d q ) a k φ ( n ) ≡ 1 ( m o d q ) 令 m 为 整 数 , 有 a k φ ( n ) = m q + 1 a k φ ( n ) + 1 = m a q + a 将 a 分 解 为 a = x p a k φ ( n ) + 1 = m x p q + a = m x n + a 则 a k φ ( n ) + 1 ≡ a ( m o d n ) 成 立 若a与n不互质,必有p|a(p能被a整除)或者q|a。设p|a成立,必有gcd(q,a)=1,否则n|a,不符合题设条件。\\同理设q|a成立也是一样的情况,不失一般性,设p|a成立。 由欧拉定理和\varphi(n)=(p-1)(q-1)得到:\\ a^{\varphi(n)}\equiv 1(\mod q) \\ a^{k\varphi(n)}\equiv 1(\mod q) \\ 令m为整数,有\\ a^{k\varphi(n)}=mq+1\\ a^{k\varphi(n) + 1}=maq+a\\ 将a分解为a=xp \\ a^{k\varphi(n) + 1}=mxpq+a=mxn+a\\ 则a^{k\varphi(n) + 1}\equiv a(\mod n)成立
若a与n不互质,必有p∣a(p能被a整除)或者q∣a。设p∣a成立,必有gcd(q,a)=1,否则n∣a,不符合题设条件。
同理设q∣a成立也是一样的情况,不失一般性,设p∣a成立。由欧拉定理和φ(n)=(p−1)(q−1)得到:
a
φ(n)
≡1(modq)
a
kφ(n)
≡1(modq)
令m为整数,有
a
kφ(n)
=mq+1
a
kφ(n)+1
=maq+a
将a分解为a=xp
a
kφ(n)+1
=mxpq+a=mxn+a
则a
kφ(n)+1
≡a(modn)成立
运行结果如下: