欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

RSA算法C语言实现

程序员文章站 2022-07-02 15:52:50
一、源文件三个rsa.h , rsa.c , main.c //rsa.h #include #define max_num 63001 #define max_prime 251...

一、源文件三个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;
}

二 运行

RSA算法C语言实现