在实际应用中,发现上次贴出来的测试代码里由不少问题,特此更新。
问题集中在:
1,怎么设置密钥相关变量mpuint的长度?
2,怎么设置明文、密文变量mpuint的长度?
原文是这么写的:
The variables d, e and n must be the same length, which must be an even multiple of 16 bits.
The source must be less than the modulus n(解密时,密文也应该小于n)
如果需要明文的ascii最大长度是64,
unsigned iMaxTextLen = 64;
unsigned iMaxKeyLen = (iMaxTextLen/2+2);
把64个byte换算成word。再加几个word,避免按照字符串输出时没有空结尾。
在加密解密过程中,所需mpuint的长度都可以初始化为iMaxKeyLen。
如果对数学原理很清楚的话,相信对上述问题就一目了然了。
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
还有半小时下班,抓紧。
========================================================
RSA库:
http://www.efgh.com/software/rsa.htm
选择理由:开源,简单明白。大侠推荐,品质保证。
========================================================
参考资料:
RSA库可选方案:
RSA encryption library for c++,http://stackoverflow.com/questions/108518/rsa-encryption-library-for-c
RSA演示:
http://people.eku.edu/styere/Encrypt/RSAdemo.html#genp
RSA加密演算法,
http://zh.wikipedia.org/zh/RSA%E5%8A%A0%E5%AF%86%E6%BC%94%E7%AE%97%E6%B3%95
同余,
http://zh.wikipedia.org/wiki/%E5%90%8C%E4%BD%99
互质,
http://zh.wikipedia.org/wiki/%E4%BA%92%E8%B3%AA
欧拉函数,
http://zh.wikipedia.org/wiki/%E6%AC%A7%E6%8B%89%E5%87%BD%E6%95%B0
========================================================
测试代码:
注意:需要定义rsa库的外部函数
void numeric_overflow(void)
{
perror( "numeric overflow" );
abort();
}
#include "stdafx.h"
#include <stdlib.h>
#include <string.h>
#include <memory.h>
#include <RsaLib\RSA.H>
int _tmain(int argc, _TCHAR* argv[])
{
printf("== mpuint功能测试 ===========================================\r\n");
mpuint i(2);
memset(i.value, 0, sizeof(*i.value)*i.length);
// mpuint单位长度:2个字节,1个unicode
printf("unsigned short.sizeof ===> %d\r\n", sizeof(unsigned short));
// mpuint总体长度:2个单位,4个字节,2个unicoder
printf("i.sizeof ===> %d\r\n", i.length * sizeof(*i.value));
{
printf("== 逐个单位的输入\r\n");
// 赋值
unsigned short *pValue = i.value;
pValue = i.value;
*pValue = 1;
pValue++;
*pValue = 3;
// 按mpuint单位输出
pValue = i.value;
for (size_t j=0; j<i.length; j++)
{
printf("i[%d] = %d\r\n", j, *pValue);
pValue++;
}
// edit:按照10进制输出到字符串
char szI[1024];
printf("i.edit ===> %s\r\n", i.edit(szI));
long l = atol(szI);
printf("i.edit.printf.0x ===> %0x\r\n", l);
// dump:按照mpuint.value[i]逐个输出到控制台
//
低位单元先输出,高位单元后输出
printf("i.dump ===>");
i.dump();
// scan: 用10进制形式的字符串给mpuint赋值
mpuint s(i.length);
const char* pszI = szI;
s.scan(pszI);
printf("i.edit.scan.dump ===>"); s.dump();
}
{
printf("== 输入字符串\r\n");
// 赋值
char szSource[] = {"ab"};
const char* pszSource = szSource;
memset(i.value, 0, i.length*sizeof(*i.value));
memcpy(i.value, szSource, strlen(szSource));
unsigned short *pValue = i.value;
// 按mpuint单位输出
pValue = i.value;
for (size_t j=0; j<i.length; j++)
{
printf("i[%d] = %d\r\n", j, *pValue);
pValue++;
}
// edit:按照10进制输出到字符串
char szI[1024];
printf("i.edit ===> %s\r\n", i.edit(szI));
long l = atol(szI);
printf("i.edit.printf.0x ===> %0x\r\n", l);
// dump:按照mpuint.value[i]逐个输出到控制台
//
低位单元先输出,高位单元后输出
printf("i.dump ===>");
i.dump();
// scan: 用10进制形式的字符串给mpuint赋值
mpuint s(i.length);
const char* pszI = szI;
s.scan(pszI);
printf("i.edit.scan.dump ===>"); s.dump();
}
printf("\r\n");
printf("== RSA功能测试 ==============================================\r\n");
// 最大(ascii)明文长度
unsigned iMaxTextLen = 64;
// 521bit
unsigned iMaxKeyLen = (iMaxTextLen/2+2);
// 已知字符串形式的明文szSource
//
/* 超长
char szSource[] = {"1234567890123456789012345678901234567890123456789012345678901234_"}; */
char szSource[] = {"1234567890123456789012345678901234567890123456789012345678901234"};
//
char szSource[] = {"HYTE7M1K4K9U4CW1_HYTE7M1K4K9U4CW1_HYTE7M1K4K9U4CW1"};
//
char szSource[] = {"HYTE7M1K4K9U4CW1"};
//
char szSource[] = {"HYTE7M1"};
unsigned iTextLen = (unsigned)strlen(szSource);
printf("szSource ===> %s\r\n", szSource);
// 生成密钥
// 注意:den必须长度一致, 而且是16bit的倍数
mpuint d(iMaxKeyLen);
// 私钥.exponent
mpuint e(iMaxKeyLen);
// 公钥.exponent
mpuint n(iMaxKeyLen);
// moudle
/* 从字符串导入 */
char szD[] = "1366959476314201320612104229499274776898462169097826485636934\
0755196674896840342671642725095343222587647553252671687501273973225252986923047\
686286753753292800187223";
char szE[] = "7364464467100835015079598280779551627848613277390947205308161\
0017571755159810471970615094708039828625362188996500904870853267420683968471425\
23360654194537840151975";
char szN[] = "2551046374903721556165087556621364411613628475298617149406045\
5273705136007088455713120641125241943821666337305259447948524285690486822556554\
630571721143649549902363";
const char* pszScan;
d.scan(pszScan = szD);
e.scan(pszScan = szE);
n.scan(pszScan = szN);
/* 动态生成 */
//
GenerateKeys(d, e, n);
char szKey[1024];
printf("d ===> "); d.dump(); printf("%s\r\n", d.edit(szKey));
printf("e ===> "); e.dump(); printf("%s\r\n", e.edit(szKey));
printf("n ===> "); n.dump(); printf("%s\r\n", n.edit(szKey));
// 加密:输入字符串形式的明文szSource和公钥pk, 输出字符串形式的密文szResult_Encrypt
// 注意:source必须小于n
mpuint source(iMaxKeyLen);
memset(source.value, 0, source.length*sizeof(*source.value));
memcpy(source.value, szSource, strlen(szSource));
printf("source ===> "); source.dump();
if (!(source < n))
{
printf("!!! assert ===> when encrypt, source < n. \r\n");
}
mpuint result_Encrypt(iMaxKeyLen);
EncryptDecrypt(result_Encrypt, source, e, n);
printf("result_Encrypt ===> "); result_Encrypt.dump();
char szResult_Encrypt[1024];
printf("%s\r\n", result_Encrypt.edit(szResult_Encrypt));
// 解密:输入字符串显示的密文szResult_Encrypt和私钥sk,输出字符串显示的明文
if (!(result_Encrypt < n)) // 注意:source必须小于n
{
printf("!!! assert ===> when decrypt, result_Encrypt < n. \r\n");
}
mpuint result_Decrypt_In(iMaxKeyLen);
const char* pszResult_EnCrypt = szResult_Encrypt;
result_Decrypt_In.scan(pszResult_EnCrypt);
mpuint result_Decrypt(iMaxKeyLen);
EncryptDecrypt(result_Decrypt, result_Decrypt_In, d, n);
printf("result_Decrypt ===> "); result_Decrypt.dump();
// 输出
printf("szResult ===> %s\r\n", (char*)(result_Decrypt.value));
printf("szSource ===> %s\r\n", szSource);
return 0;
}
========================================================
部分测试结果:
== mpuint功能测试
unsigned short.sizeof ===> 2
i.sizeof ===> 4
i[0] = 1
i[1] = 3
i.edit ===> 196609
i.edit.printf.0x ===> 30001
i.dump ===> 0001 0003
i.edit.scan.dump ===> 0001 0003
========================================================
哦也,15分钟完成。