密码学RSA算法通过C++实现

sunner543 2008-04-02 01:50:15
听说你是RSA的达人。能帮我解释一下下面的程序么我是C++菜鸟。大概知道前面的是为了实现大数计算。最后一段RSA好象把p,q,m,都设定好了。最后一段如果可以的话每行啥意思。讲下谢谢哈

//头文件BigInt.h

#ifndef BIGINT_H
#define BIGINT_H


#define BI_MAXLEN 8

class CBigInt
{
public:
unsigned m_nLength;
unsigned long m_ulValue[BI_MAXLEN];
CBigInt();

void Mov(unsigned __int64 A);
void Mov(CBigInt& A);
CBigInt Sub(CBigInt& A);
CBigInt Mul(CBigInt& A);
CBigInt Mod(CBigInt& A);
CBigInt Sub(unsigned long A);
CBigInt Mul(unsigned long A);
CBigInt Div(unsigned long A);
unsigned long Mod(unsigned long A);
int Cmp(CBigInt& A);
CBigInt ModExp(CBigInt& A, CBigInt& B);
};

#endif

//原文件BigInt.cpp

#include "BigInt.h"

//构造大数对象并初始化为零
CBigInt::CBigInt()
{
m_nLength=1;
for(int i=0;i<BI_MAXLEN;i++)m_ulValue[i]=0;
}


//大数比较
int CBigInt::Cmp(CBigInt& A)
{
if(m_nLength>A.m_nLength)return 1;
if(m_nLength<A.m_nLength)return -1;
for(int i=m_nLength-1;i>=0;i--)
{
if(m_ulValue[i]>A.m_ulValue[i])return 1;
if(m_ulValue[i]<A.m_ulValue[i])return -1;
}
return 0;
}

//大数赋值
void CBigInt::Mov(CBigInt& A)
{
m_nLength=A.m_nLength;
for(int i=0;i<BI_MAXLEN;i++)
m_ulValue[i]=A.m_ulValue[i];
}
void CBigInt::Mov(unsigned __int64 A)
{
if(A>0xffffffff)
{
m_nLength=2;
m_ulValue[1]=(unsigned long)(A>>32);
m_ulValue[0]=(unsigned long)A;
}
else
{
m_nLength=1;
m_ulValue[0]=(unsigned long)A;
}
for(int i=m_nLength;i<BI_MAXLEN;i++)m_ulValue[i]=0;
}

//大数相减
CBigInt CBigInt::Sub(CBigInt& A)
{
CBigInt X;
X.Mov(*this);
if(X.Cmp(A)<=0){X.Mov(0);return X;}
unsigned carry=0;
unsigned __int64 num;
unsigned i;
for(i=0;i<m_nLength;i++)
{
if((m_ulValue[i]>A.m_ulValue[i])||((m_ulValue[i]==A.m_ulValue[i])&&(carry==0)))
{
X.m_ulValue[i]=m_ulValue[i]-carry-A.m_ulValue[i];
carry=0;
}
else
{
num=0x100000000+m_ulValue[i];
X.m_ulValue[i]=(unsigned long)(num-carry-A.m_ulValue[i]);
carry=1;
}
}
while(X.m_ulValue[X.m_nLength-1]==0)X.m_nLength--;
return X;
}


CBigInt CBigInt::Sub(unsigned long A)
{
CBigInt X;
X.Mov(*this);
if(X.m_ulValue[0]>=A){X.m_ulValue[0]-=A;return X;}
if(X.m_nLength==1){X.Mov(0);return X;}
unsigned __int64 num=0x100000000+X.m_ulValue[0];
X.m_ulValue[0]=(unsigned long)(num-A);
int i=1;
while(X.m_ulValue[i]==0){X.m_ulValue[i]=0xffffffff;i++;}
X.m_ulValue[i]--;
if(X.m_ulValue[i]==0)X.m_nLength--;
return X;
}

//大数相乘
CBigInt CBigInt::Mul(CBigInt& A)
{
if(A.m_nLength==1)return Mul(A.m_ulValue[0]);
CBigInt X;
unsigned __int64 sum,mul=0,carry=0;
unsigned i,j;
X.m_nLength=m_nLength+A.m_nLength-1;
for(i=0;i<X.m_nLength;i++)
{
sum=carry;
carry=0;
for(j=0;j<A.m_nLength;j++)
{
if(((i-j)>=0)&&((i-j)<m_nLength))
{
mul=m_ulValue[i-j];
mul*=A.m_ulValue[j];
carry+=mul>>32;
mul=mul&0xffffffff;
sum+=mul;
}
}
carry+=sum>>32;
X.m_ulValue[i]=(unsigned long)sum;
}
if(carry){X.m_nLength++;X.m_ulValue[X.m_nLength-1]=(unsigned long)carry;}
return X;
}


CBigInt CBigInt::Mul(unsigned long A)
{
CBigInt X;
unsigned __int64 mul;
unsigned long carry=0;
X.Mov(*this);
for(unsigned i=0;i<m_nLength;i++)
{
mul=m_ulValue[i];
mul=mul*A+carry;
X.m_ulValue[i]=(unsigned long)mul;
carry=(unsigned long)(mul>>32);
}
if(carry){X.m_nLength++;X.m_ulValue[X.m_nLength-1]=carry;}
return X;
}

//大数相除
CBigInt CBigInt::Div(unsigned long A)
{
CBigInt X;
X.Mov(*this);
if(X.m_nLength==1){X.m_ulValue[0]=X.m_ulValue[0]/A;return X;}
unsigned __int64 div,mul;
unsigned long carry=0;
for(int i=X.m_nLength-1;i>=0;i--)
{
div=carry;
div=(div<<32)+X.m_ulValue[i];
X.m_ulValue[i]=(unsigned long)(div/A);
mul=(div/A)*A;
carry=(unsigned long)(div-mul);
}
if(X.m_ulValue[X.m_nLength-1]==0)X.m_nLength--;
return X;
}


//大数求模
CBigInt CBigInt::Mod(CBigInt& A)
{
if(A.m_nLength==1)
{
CBigInt X;
X.m_ulValue[0]=Mod(A.m_ulValue[0]);
return X;
}
CBigInt X,Y;
int len;
unsigned __int64 num,div;
unsigned long carry=0;
X.Mov(*this);
while(X.Cmp(A)>0)
{
if(X.m_ulValue[X.m_nLength-1]>A.m_ulValue[A.m_nLength-1])
{
len=X.m_nLength-A.m_nLength;
div=X.m_ulValue[X.m_nLength-1]/(A.m_ulValue[A.m_nLength-1]+1);
}
else if(X.m_nLength>A.m_nLength)
{
len=X.m_nLength-A.m_nLength-1;
num=X.m_ulValue[X.m_nLength-1];
num=(num<<32)+X.m_ulValue[X.m_nLength-2];
if(A.m_ulValue[A.m_nLength-1]==0xffffffff)div=(num>>32);
else div=num/(A.m_ulValue[A.m_nLength-1]+1);
}
else
{
X.Mov(X.Sub(A));
break;
}
Y.Mov(div);
Y.Mov(Y.Mul(A));
Y.m_nLength+=len;
for(int i=Y.m_nLength-1;i>=len;i--) Y.m_ulValue[i]=Y.m_ulValue[i-len];
for(i=0;i<len;i++) Y.m_ulValue[i]=0;
X.Mov(X.Sub(Y));
}
if(X.Cmp(A)==0)X.Mov(0);
return X;
}

unsigned long CBigInt::Mod(unsigned long A)
{
if(m_nLength==1)return(m_ulValue[0]%A);
unsigned __int64 div;
unsigned long carry=0;
for(int i=m_nLength-1;i>=0;i--)
{
div=carry*0x100000000+m_ulValue[i];
carry=(unsigned long)(div-((div/A)*A));
}
return carry;
}





//蒙哥马利算法求模幂
CBigInt CBigInt::ModExp(CBigInt& A, CBigInt& B)
{
CBigInt X,Y,Z;
X.Mov(1);
Y.Mov(*this);
Z.Mov(A);
while((Z.m_nLength!=1)||Z.m_ulValue[0])
{
if(Z.m_ulValue[0]&1)
{
Z.Mov(Z.Sub(1));
X.Mov(X.Mul(Y));
X.Mov(X.Mod(B));
}
else
{
Z.Mov(Z.Div(2));
Y.Mov(Y.Mul(Y));
Y.Mov(Y.Mod(B));
}
}
return X;
}

//原文件主程序RSA.cpp

#include "BigInt.h"
#include <stdio.h>

int main(int argc, char* argv[])
{
CBigInt m,e,n,d,c,m1;
int i;

m.m_nLength=4;
m.m_ulValue[3]=0x0;
m.m_ulValue[2]=0x0;
m.m_ulValue[1]=0x0;
m.m_ulValue[0]=0x45e;

printf("The initial plainttext m is:\n");
for(i=BI_MAXLEN-5;i>=0;i--)
printf("%x\n",m.m_ulValue[i]);


e.m_nLength=1;
e.m_ulValue[0]=0x34703;

n.m_nLength=4;
n.m_ulValue[3]=0x78CDED41;
n.m_ulValue[2]=0xF71A0BF9;
n.m_ulValue[1]=0xA1F36E0A;
n.m_ulValue[0]=0x60F3EE89;


c.Mov(m.ModExp(e,n));

printf("The ciphertext encrypted c is:\n");
for(i=BI_MAXLEN-5;i>=0;i--)
printf("%x\n",c.m_ulValue[i]);


d.m_nLength=4;
d.m_ulValue[3]=0x4C9327F3;
d.m_ulValue[2]=0x70B028FD;
d.m_ulValue[1]=0x08D56387;
d.m_ulValue[0]=0xFCC6161B;

m1.Mov(c.ModExp(d,n));

printf("The plainttext decrypted m1 is:\n");
for(i=BI_MAXLEN-5;i>=0;i--)
printf("%x\n",m1.m_ulValue[i]);



return 0;
}
...全文
1113 12 打赏 收藏 转发到动态 举报
写回复
用AI写文章
12 条回复
切换为时间正序
请发表友善的回复…
发表回复
m0306011011163 2011-07-27
  • 打赏
  • 举报
回复
确实很有用,不过大数库封装的不全!
ly_bianweilan 2010-12-09
  • 打赏
  • 举报
回复
好吧,08年的帖子,仍然实用无论对我们的编码学习还是密码学的学习,都很有帮助,顶了……
mike442144 2009-10-11
  • 打赏
  • 举报
回复
kankanxuexi
misswjc 2009-03-20
  • 打赏
  • 举报
回复
很好,很强大!
sunner543 2008-04-06
  • 打赏
  • 举报
回复
你太有才了。分先给你。我好好看看先
060 2008-04-05
  • 打赏
  • 举报
回复
根据RSA算法, p和q的值需要满足非常苛刻的条件。一般情况下,生成一对p和q也需要一个算法。

把RSA算法的应用过程分3类:
> 生密钥, 生成公钥和私钥, 就是找一对p和q,还有n。
n和z就作为公钥。 在以后的加解密操作中可以不使用p和q
> 公钥运算
> 私钥运算

int Cmp(CBigInt& A); 
CBigInt ModExp(CBigInt& A, CBigInt& B);
};


int main(int argc, char* argv[])
{
CBigInt m,e,n,d,c,m1;
int i;

// 需要加解密的信息
m.m_nLength=4;
m.m_ulValue[3]=0x0;
m.m_ulValue[2]=0x0;
m.m_ulValue[1]=0x0;
m.m_ulValue[0]=0x45e;

printf("The initial plainttext m is:\n");
for(i=BI_MAXLEN-5;i>=0;i--)
printf("%x\n",m.m_ulValue[i]);


// 公钥指数, 一般为3、17、65537,也可以为是其它一个素数,
e.m_nLength=1;
e.m_ulValue[0]=0x34703;

// 模数n, 一个大素数
n.m_nLength=4;
n.m_ulValue[3]=0x78CDED41;
n.m_ulValue[2]=0xF71A0BF9;
n.m_ulValue[1]=0xA1F36E0A;
n.m_ulValue[0]=0x60F3EE89;

// 加密过程
// c = (m^e) % n;
// c就是密文
c.Mov(m.ModExp(e,n));

printf("The ciphertext encrypted c is:\n");
for(i=BI_MAXLEN-5;i>=0;i--)
printf("%x\n",c.m_ulValue[i]);

// 私钥指数, 与e对应
d.m_nLength=4;
d.m_ulValue[3]=0x4C9327F3;
d.m_ulValue[2]=0x70B028FD;
d.m_ulValue[1]=0x08D56387;
d.m_ulValue[0]=0xFCC6161B;

// 解密操作
// m1 = (c^d) % n
// m1 就是得到的明文, 它的值应当等于 m.
m1.Mov(c.ModExp(d,n));

printf("The plainttext decrypted m1 is:\n");
for(i=BI_MAXLEN-5;i>=0;i--)
printf("%x\n",m1.m_ulValue[i]);



return 0;
}
sunner543 2008-04-05
  • 打赏
  • 举报
回复
你说的原理我都懂。就是看不懂程序。c++菜鸟。这个程序的p,q值和m已经设置好了的。你知道哪个是p,q么?我就是看懂程序才问的。至于RSA的算法我还是知道的。。`~~~
钢都百炼生 2008-04-04
  • 打赏
  • 举报
回复
复杂
星羽 2008-04-04
  • 打赏
  • 举报
回复
up 2002
不想低调 2008-04-04
  • 打赏
  • 举报
回复
up
laolaoliu2002 2008-04-04
  • 打赏
  • 举报
回复
RSA公钥加密算法基于大整数因式分解困难这样的事实。
选择两个素数,p,q。(一般p,q选择很大的数)
然后计算 z=p*q f=(p-1)(q-1) 选择一个n,使gcd(n,f)=1(gcd代表greatest common divider,一般n也选择一个素数), n和z就作为公钥。
选择一个s,0<s<f,满足n*s % f=1,s就作为私钥。

为了发送一个整数a,0<a<z-1,发送者通过接收者的公钥计算 c=a^n % z,然后发送c。
解密这个数就计算c^s % z。
在计算a^n %z时,如果n比较大,那么采用通常的方法计算会非常困难,可以采用下面的公式来计算
a*b % z=[(a % z)(b % z)] mod z (容易证明)

例如:计算572^29 mod 713, 29=16+8+4+1(基于2的表示) 572^2 % 713=327184 % 713 =630 572^4 % 713=[(572^2 % 713)(572^2 % 713)] % 713=630^2 % 713=472
laolaoliu2002 2008-04-04
  • 打赏
  • 举报
回复
没问我我就不说,哈哈.
看看RSA加密的原理然后把程序调试跟踪一下就明白了撒.

33,311

社区成员

发帖
与我相关
我的任务
社区描述
C/C++ 新手乐园
社区管理员
  • 新手乐园社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧