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; }
二 运行
上一篇: C语言空指针NULL以及void指针
下一篇: 简单C语言程序