当前位置: 移动技术网 > IT编程>开发语言>C/C++ > RSA算法C语言实现

RSA算法C语言实现

2018年10月22日  | 移动技术网IT编程  | 我要评论

水中月亮简谱,人民币与韩币汇率,未来新能源

一、源文件三个rsa.h , rsa.c , main.c

//rsa.h
#include 
#define max_num 63001
#define max_prime 251

//! 返回代码
#define ok 100
#define error_noeachprime 101
#define error_nopublickey 102
#define error_generror 103

unsigned int makeprivatedkeyd( unsigned int uip, unsigned int uiq );
unsigned int getprivatekeyd( unsigned int iwhich );
unsigned int makepairkey( unsigned int uip, unsigned int uiq, unsigned int uid );
unsigned int getpairkey( unsigned int &d, unsigned int &e );
void rsa_encrypt( int n, int e, char *mw, int ilength, int *&cw );
void rsa_decrypt( int n, int d, int *&cw, int clength, char *mw );
void outputkey();

//rsa.c
#include "rsa.h"
//! 保存私钥d集合
struct pkeyset
{
unsigned int set[ max_num ];
unsigned int size;
}pset;

//! 保存公、私钥对
struct ppairkey
{
unsigned int d;
unsigned int e;
unsigned int n;
}pairkey;

// 名称:isprime
// 功能:判断两个数是否互质
//  参数:m: 数a; n: 数b
// 返回:m、n互质返回true; 否则返回false

bool isprime( unsigned int m, unsigned int n )
{
unsigned int i=0;
bool flag = true;

if( m<2 || n<2 )
return false;

unsigned int tem = ( m > n ) ? n : m;
for( i=2; i<=tem && flag; i++ )
{
bool mflag = true;
bool nflag = true;
if( m % i == 0 )
mflag = false;
if( n % i == 0 )
nflag = false;
if( !mflag && !nflag )
flag = false;
}
if( flag )
return true;
else
return false;
}

// 名称:makeprivatedkeyd
// 功能:由素数q、q生成私钥d
//  参数:uip: 素数p; uiq: 素数q
// 返回:私钥d

unsigned int makeprivatedkeyd( unsigned int uip, unsigned int uiq )
{
unsigned int i=0;

//! 得到所有与z互质的数( 私钥d的集合 )
unsigned int z = ( uip -1 ) * ( uiq -1 );
pset.size = 0;
for( i=0; i= iwhich )
return pset.set[ iwhich ];
else
return 0;
}

// 名称:rsa_encrypt
// 功能:rsa加密运算
//  参数:n: 公钥n; e: 公钥e; mw: 加密明文; ilength: 明文长度; cw: 密文输出
// 返回:无

void rsa_encrypt( int n, int e, char *mw, int mlength, int *&cw )
{
int i=0, j=0;
__int64 temint = 0;

for( i=0; i
#include 
#include 
#include "rsa.h"

#define decrypt_file "rsa加密密文.txt"
#define encrypt_file "rsa解密明文.txt"
//! 约束文件最大2m
#define max_file 1024*1024*2

// 名称:usage
// 功能:帮助信息
//  参数:应用程序名称
// 返回:提示信息

void usage( const char *appname )
{
printf( "\n\tusage:rsa -k 素数p 素数q\n" );
printf( "\tusage: rsa -e 明文文件 公钥e 公钥n\n" );
printf( "\tusage: rsa -d 密文文件 私钥d 私钥n\n" );
}

// 名称:isnumber
// 功能:判断数字字符数组
//  参数:strnumber:字符数组
// 返回:数字字组数组返回true,否则返回false;

bool isnumber( const char *strnumber )
{
unsigned int i;

if( !strnumber )
return false;

for ( i = 0 ; i < strlen(strnumber) ; i++ )
{
if ( strnumber[i] < '0' || strnumber[i] > '9' )
return false;
}

return true;
}

// 名称:isprimenumber
// 功能:判断素数
//  参数:num: 输入整数
// 返回:素数返回true,否则返回false;

bool isprimenumber( unsigned int num )
{
unsigned int i;
if( num <= 1 )
return false;

unsigned int sqr = (unsigned int)sqrt((double)num);
for( i = 2; i <= sqr; i++ )
{
if( num % i == 0 )
return false;
}

return true;
}

// 名称:filein
// 功能:读取磁盘文件到内存
//  参数:strfile:文件名称;inbuff:指向文件内容缓冲区
// 返回:实际读取内容大小(字节)

int filein( const char *strfile, unsigned char *&inbuff )
{
int ifilelen=0, ibufflen=0;

//! 打开密文文件
cfile file( strfile, cfile::moderead );
ifilelen = ( int )file.getlength();
if( ifilelen>max_file )
{
printf( "文件长度不能大于 %dm,!\n", max_file/(1024*1024) );
goto out;
}
ibufflen = ifilelen;

inbuff = new unsigned char[ibufflen];
if( !inbuff )
goto out;

zeromemory( inbuff, ibufflen );

file.read( inbuff, ifilelen );
file.close();

out:
return ibufflen;
}

// 名称:fileout
// 功能:加/解密结果输出到当前目录磁盘文件中
//  参数:strout指向输出字符缓冲区,输出大小len,strfile为输出文件
// 返回:无

void fileout( const void *strout, int len, const char *strfile )
{
//! 输出到文件
cfile outfile( strfile , cfile::modecreate | cfile::modewrite );
outfile.write( strout , len );
outfile.close();
}

// 名称:checkparse
// 功能:校验应用程序入口参数
//  参数:argc等于main主函数argc参数,argv指向main主函数argv参数
// 返回:若参数合法返回true,否则返回false
//  备注:简单的入口参数校验

bool checkparse( int argc, char** argv )
{
bool bres = false;

if( argc != 4 && argc != 5 )
goto out;

if( argc == 4 && argv[1][1] == 'k' )
{
//! 生成公、私钥对
if( !isnumber( argv[2] ) || 
!isnumber( argv[3] ) ||
atoi( argv[2] ) > max_prime ||
atoi( argv[3] ) > max_prime )
goto out;
}
else if( (argc == 5) && (argv[1][1] == 'e' || argv[1][1] == 'd') )
{
//! 加密、解密操作
if( !isnumber( argv[3] ) ||
!isnumber( argv[4] ) ||
atoi( argv[3] ) > max_num ||
atoi( argv[4] ) > max_num )
goto out;
}
else
usage(*argv);
bres = true;

out:
return bres;
}

// 名称:koption1
// 功能:程序k选项操作:由素数p、q生成私钥d集合
//  参数:uip: 程序入口参数p; uiq: 程序入口参数q
// 返回:执行正确返回生成私钥数目,否则返回0

unsigned int koption1( unsigned int uip, unsigned int uiq )
{
unsigned int uires = 0;

if( !isprimenumber( uip ) )
{
printf( "p输入错误,p必须为(0, %d]素数", max_prime );
return uires;
}
if( !isprimenumber( uiq ) )
{
printf( "q输入错误,q必须为(0, %d]素数", max_prime );
return uires;
}
if( uip == uiq )
{
printf( "素数p与素数q相同,很容易根据公钥n开平方得出素数p和q,这种加密不安全,请更换素数!\n" );
return uires;
}
printf( "正在生成私钥d集合......\n" );
uires = makeprivatedkeyd( uip, uiq );

return uires;
}

//! 程序主函数
int main( int argc, char **argv )
{
unsigned int p , q , d , n , e;//two prime p & q, public key(n, e) , private key(n , d)
checkparse(argc,  argv );

d=4828; //uid
if(argc == 4)
{
p = atoi( argv[2] );
q = atoi( argv[3] );
makeprivatedkeyd(p, q);
makepairkey(p, q, d );
outputkey();
}
else if(argc == 5)
{
char filename[20];
strcpy(filename, argv[2]);
int len;
if(argv[1][1] == 'e' )
{
unsigned char *inbuffer=(unsigned char *)malloc(max_file); //输入缓冲区
int *cw=(int *)malloc(max_file);
len = filein(filename , inbuffer);
e = atoi(argv[3]);
n = atoi(argv[4]);
rsa_encrypt( n, e, (char *)inbuffer, len, cw );
fileout( cw, 4*len, decrypt_file );
}
else if(argv[1][1] == 'd')
{
char *buffer=(char *)malloc(max_file); //输入缓冲区
int *cw=(int *)malloc(max_file);
len = filein(filename, (unsigned char *&)cw);
d = atoi(argv[3]);
n = atoi(argv[4]);
rsa_decrypt( n, d, cw, len, buffer );
fileout( buffer, len/4, encrypt_file );
}
}

return 0;
}

二 运行

\

如对本文有疑问,请在下面进行留言讨论,广大热心网友会与你互动!! 点击进行留言回复

相关文章:

验证码:
移动技术网