当前位置:首页 > 代码 > 正文

rsa数字签名源代码(rsa签名算法采用了什么密码算法)

admin 发布:2022-12-19 16:51 142


今天给各位分享rsa数字签名源代码的知识,其中也会对rsa签名算法采用了什么密码算法进行解释,如果能碰巧解决你现在面临的问题,别忘了关注本站,现在开始吧!

本文目录一览:

求RSA/MD5数字签名系统源码!

/* MD5lib.h - md5 library

*/

/* Copyright (C) 1990-2, RSA Data Security, Inc. Created 1990. All

rights reserved.

RSA Data Security, Inc. makes no representations concerning either

the merchantability of this software or the suitability of this

software for any particular purpose. It is provided "as is"

without express or implied warranty of any kind.

These notices must be retained in any copies of any part of this

documentation and/or software.

*/

/* The following makes MD default to MD5 if it has not already been

defined with C compiler flags.

*/

#include stdio.h

#include time.h

#include string.h

#define MD 5

/* GLOBAL.H - RSAREF types and constants

*/

/* PROTOTYPES should be set to one if and only if the compiler supports

function argument prototyping.

The following makes PROTOTYPES default to 0 if it has not already

been defined with C compiler flags.

*/

#ifndef PROTOTYPES

#define PROTOTYPES 0

#endif

/* POINTER defines a generic pointer type */

typedef unsigned char *POINTER;

/* UINT2 defines a two byte word */

typedef unsigned short int UINT2;

/* UINT4 defines a four byte word */

typedef unsigned long int UINT4;

/* PROTO_LIST is defined depending on how PROTOTYPES is defined above.

If using PROTOTYPES, then PROTO_LIST returns the list, otherwise it

returns an empty list.

*/

#if PROTOTYPES

#define PROTO_LIST(list) list

#else

#define PROTO_LIST(list) ()

#endif

/* Length of test block, number of test blocks.

*/

#define TEST_BLOCK_LEN 1000

#define TEST_BLOCK_COUNT 1000

/* Constants for MD5Transform routine.

*/

#define S11 7

#define S12 12

#define S13 17

#define S14 22

#define S21 5

#define S22 9

#define S23 14

#define S24 20

#define S31 4

#define S32 11

#define S33 16

#define S34 23

#define S41 6

#define S42 10

#define S43 15

#define S44 21

char* MDString PROTO_LIST ((char *));

char* MDFile PROTO_LIST ((char *));

char* hmac_md5(char* text, char* key);

typedef struct {

UINT4 state[4]; /* state (ABCD) */

UINT4 count[2]; /* number of bits, modulo 2^64 (lsb first) */

unsigned char buffer[64]; /* input buffer */

} MD5_CTX;

/*void MD5Init PROTO_LIST ((MD5_CTX *));

void MD5Update PROTO_LIST

((MD5_CTX *, unsigned char *, unsigned int));

void MD5Final PROTO_LIST ((unsigned char [16], MD5_CT X *));

static void MD5Transform PROTO_LIST ((UINT4 [4], unsigned char [64]));

static void Encode PROTO_LIST

((unsigned char *, UINT4 *, unsigned int));

static void Decode PROTO_LIST

((UINT4 *, unsigned char *, unsigned int));

static void MD5_memcpy PROTO_LIST ((POINTER, POINTER, unsigned int));

static void MD5_memset PROTO_LIST ((POINTER, int, unsigned int));

*/

static unsigned char PADDING[64] = {

0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,

0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,

0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0

};

/* F, G, H and I are basic MD5 functions.

*/

#define F(x, y, z) (((x) (y)) | ((~x) (z)))

#define G(x, y, z) (((x) (z)) | ((y) (~z)))

#define H(x, y, z) ((x) ^ (y) ^ (z))

#define I(x, y, z) ((y) ^ ((x) | (~z)))

/* ROTATE_LEFT rotates x left n bits.

*/

#define ROTATE_LEFT(x, n) (((x) (n)) | ((x) (32-(n))))

/* FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4.

Rotation is separate from addition to prevent recomputation.

*/

#define FF(a, b, c, d, x, s, ac) {(a) += F ((b), (c), (d)) + (x) + (UINT4)(ac); (a) = ROTATE_LEFT ((a), (s)); (a) += (b);}

#define GG(a, b, c, d, x, s, ac) {(a) += G ((b), (c), (d)) + (x) + (UINT4)(ac); (a) = ROTATE_LEFT ((a), (s)); (a) += (b);}

#define HH(a, b, c, d, x, s, ac) {(a) += H ((b), (c), (d)) + (x) + (UINT4)(ac); (a) = ROTATE_LEFT ((a), (s)); (a) += (b);}

#define II(a, b, c, d, x, s, ac) {(a) += I ((b), (c), (d)) + (x) + (UINT4)(ac); (a) = ROTATE_LEFT ((a), (s)); (a) += (b);}

void MD5Init (MD5_CTX *context);

void MD5Update(MD5_CTX *context, unsigned char *input,unsigned int inputLen);

void MD5Final (unsigned char digest[16], MD5_CTX *context);

static void MD5Transform (UINT4 [4], unsigned char [64]) ;

static void Encode(unsigned char *, UINT4 *, unsigned int);

static void Decode (UINT4 *, unsigned char *, unsigned int);

static void MD5_memcpy(POINTER, POINTER, unsigned int);

static void MD5_memset(POINTER, int, unsigned int);

/* MD5 initialization. Begins an MD5 operation, writing a new context.

*/

void MD5Init (MD5_CTX *context)

/* context */

{

context-count[0] = context-count[1] = 0;

/* Load magic initialization constants.

*/

context-state[0] = 0x67452301;

context-state[1] = 0xefcdab89;

context-state[2] = 0x98badcfe;

context-state[3] = 0x10325476;

}

/* MD5 block update operation. Continues an MD5 message-digest

operation, processing another message block, and updating the

context.

*/

void MD5Update (MD5_CTX *context, unsigned char *input,unsigned int inputLen )

/* context */

/* input block */

/* length of input block */

{

unsigned int i, index, partLen;

/* Compute number of bytes mod 64 */

index = (unsigned int)((context-count[0] 3) 0x3F);

/* Update number of bits */

if ((context-count[0] += ((UINT4)inputLen 3))

((UINT4)inputLen 3))

context-count[1]++;

context-count[1] += ((UINT4)inputLen 29);

partLen = 64 - index;

/* Transform as many times as possible.

*/

if (inputLen = partLen) {

MD5_memcpy

((POINTER)context-buffer[index], (POINTER)input, partLen);

MD5Transform (context-state, context-buffer);

for (i = partLen; i + 63 inputLen; i += 64)

MD5Transform (context-state, input[i]);

index = 0;

}

else

i = 0;

/* Buffer remaining input */

MD5_memcpy

((POINTER)context-buffer[index], (POINTER)input[i],

inputLen-i);

}

/* MD5 finalization. Ends an MD5 message-digest operation, writing the

the message digest and zeroizing the context.

*/

void MD5Final (unsigned char digest[16], MD5_CTX *context)

/* message digest */

/* context */

{

unsigned char bits[8];

unsigned int index, padLen;

/* Save number of bits */

Encode (bits, context-count, 8);

/* Pad out to 56 mod 64.

*/

index = (unsigned int)((context-count[0] 3) 0x3f);

padLen = (index 56) ? (56 - index) : (120 - index);

MD5Update (context,(unsigned char*) PADDING, padLen);

/* Append length (before padding) */

MD5Update (context, bits, 8);

/* Store state in digest */

Encode (digest, context-state, 16);

/* Zeroize sensitive information.

*/

MD5_memset ((POINTER)context, 0, sizeof (*context));

}

/* MD5 basic transformation. Transforms state based on block.

*/

static void MD5Transform (UINT4 state[4],

unsigned char block[64])

{

int i=0;

UINT4 a = state[0], b = state[1], c = state[2], d = state[3], x[16];

Decode (x, block, 64);

/* Round 1 */

FF (a, b, c, d, x[ 0], S11, 0xd76aa478); /* 1 */

FF (d, a, b, c, x[ 1], S12, 0xe8c7b756); /* 2 */

FF (c, d, a, b, x[ 2], S13, 0x242070db); /* 3 */

FF (b, c, d, a, x[ 3], S14, 0xc1bdceee); /* 4 */

FF (a, b, c, d, x[ 4], S11, 0xf57c0faf); /* 5 */

FF (d, a, b, c, x[ 5], S12, 0x4787c62a); /* 6 */

FF (c, d, a, b, x[ 6], S13, 0xa8304613); /* 7 */

FF (b, c, d, a, x[ 7], S14, 0xfd469501); /* 8 */

FF (a, b, c, d, x[ 8], S11, 0x698098d8); /* 9 */

FF (d, a, b, c, x[ 9], S12, 0x8b44f7af); /* 10 */

FF (c, d, a, b, x[10], S13, 0xffff5bb1); /* 11 */

FF (b, c, d, a, x[11], S14, 0x895cd7be); /* 12 */

FF (a, b, c, d, x[12], S11, 0x6b901122); /* 13 */

FF (d, a, b, c, x[13], S12, 0xfd987193); /* 14 */

FF (c, d, a, b, x[14], S13, 0xa679438e); /* 15 */

FF (b, c, d, a, x[15], S14, 0x49b40821); /* 16 */

/* Round 2 */

GG (a, b, c, d, x[ 1], S21, 0xf61e2562); /* 17 */

GG (d, a, b, c, x[ 6], S22, 0xc040b340); /* 18 */

GG (c, d, a, b, x[11], S23, 0x265e5a51); /* 19 */

GG (b, c, d, a, x[ 0], S24, 0xe9b6c7aa); /* 20 */

GG (a, b, c, d, x[ 5], S21, 0xd62f105d); /* 21 */

GG (d, a, b, c, x[10], S22, 0x2441453); /* 22 */

GG (c, d, a, b, x[15], S23, 0xd8a1e681); /* 23 */

GG (b, c, d, a, x[ 4], S24, 0xe7d3fbc8); /* 24 */

GG (a, b, c, d, x[ 9], S21, 0x21e1cde6); /* 25 */

GG (d, a, b, c, x[14], S22, 0xc33707d6); /* 26 */

GG (c, d, a, b, x[ 3], S23, 0xf4d50d87); /* 27 */

GG (b, c, d, a, x[ 8], S24, 0x455a14ed); /* 28 */

GG (a, b, c, d, x[13], S21, 0xa9e3e905); /* 29 */

GG (d, a, b, c, x[ 2], S22, 0xfcefa3f8); /* 30 */

GG (c, d, a, b, x[ 7], S23, 0x676f02d9); /* 31 */

GG (b, c, d, a, x[12], S24, 0x8d2a4c8a); /* 32 */

/* Round 3 */

HH (a, b, c, d, x[ 5], S31, 0xfffa3942); /* 33 */

HH (d, a, b, c, x[ 8], S32, 0x8771f681); /* 34 */

HH (c, d, a, b, x[11], S33, 0x6d9d6122); /* 35 */

HH (b, c, d, a, x[14], S34, 0xfde5380c); /* 36 */

HH (a, b, c, d, x[ 1], S31, 0xa4beea44); /* 37 */

HH (d, a, b, c, x[ 4], S32, 0x4bdecfa9); /* 38 */

HH (c, d, a, b, x[ 7], S33, 0xf6bb4b60); /* 39 */

HH (b, c, d, a, x[10], S34, 0xbebfbc70); /* 40 */

HH (a, b, c, d, x[13], S31, 0x289b7ec6); /* 41 */

HH (d, a, b, c, x[ 0], S32, 0xeaa127fa); /* 42 */

HH (c, d, a, b, x[ 3], S33, 0xd4ef3085); /* 43 */

HH (b, c, d, a, x[ 6], S34, 0x4881d05); /* 44 */

HH (a, b, c, d, x[ 9], S31, 0xd9d4d039); /* 45 */

HH (d, a, b, c, x[12], S32, 0xe6db99e5); /* 46 */

HH (c, d, a, b, x[15], S33, 0x1fa27cf8); /* 47 */

HH (b, c, d, a, x[ 2], S34, 0xc4ac5665); /* 48 */

/* Round 4 */

II (a, b, c, d, x[ 0], S41, 0xf4292244); /* 49 */

II (d, a, b, c, x[ 7], S42, 0x432aff97); /* 50 */

II (c, d, a, b, x[14], S43, 0xab9423a7); /* 51 */

II (b, c, d, a, x[ 5], S44, 0xfc93a039); /* 52 */

II (a, b, c, d, x[12], S41, 0x655b59c3); /* 53 */

II (d, a, b, c, x[ 3], S42, 0x8f0ccc92); /* 54 */

II (c, d, a, b, x[10], S43, 0xffeff47d); /* 55 */

II (b, c, d, a, x[ 1], S44, 0x85845dd1); /* 56 */

II (a, b, c, d, x[ 8], S41, 0x6fa87e4f); /* 57 */

II (d, a, b, c, x[15], S42, 0xfe2ce6e0); /* 58 */

II (c, d, a, b, x[ 6], S43, 0xa3014314); /* 59 */

II (b, c, d, a, x[13], S44, 0x4e0811a1); /* 60 */

II (a, b, c, d, x[ 4], S41, 0xf7537e82); /* 61 */

II (d, a, b, c, x[11], S42, 0xbd3af235); /* 62 */

II (c, d, a, b, x[ 2], S43, 0x2ad7d2bb); /* 63 */

II (b, c, d, a, x[ 9], S44, 0xeb86d391); /* 64 */

state[0] += a;

state[1] += b;

state[2] += c;

state[3] += d;

/* Zeroize sensitive information.

*/

MD5_memset ((POINTER)x, 0, sizeof (x));

}

/* Encodes input (UINT4) into output (unsigned char). Assumes len is

a multiple of 4.

*/

static void Encode (unsigned char *output,

UINT4 *input,

unsigned int len)

{

unsigned int i, j;

for (i = 0, j = 0; j len; i++, j += 4) {

output[j] = (unsigned char)(input[i] 0xff);

output[j+1] = (unsigned char)((input[i] 8) 0xff);

output[j+2] = (unsigned char)((input[i] 16) 0xff);

output[j+3] = (unsigned char)((input[i] 24) 0xff);

}

}

/* Decodes input (unsigned char) into output (UINT4). Assumes len is

a multiple of 4.

*/

static void Decode (UINT4 *output,

unsigned char *input,

unsigned int len)

{

unsigned int i, j;

for (i = 0, j = 0; j len; i++, j += 4)

output[i] = ((UINT4)input[j]) | (((UINT4)input[j+1]) 8) |

(((UINT4)input[j+2]) 16) | (((UINT4)input[j+3]) 24);

}

/* Note: Replace "for loop" with standard memcpy if possible.

*/

static void MD5_memcpy (POINTER output,

POINTER input,

unsigned int len)

{

unsigned int i;

for (i = 0; i len; i++)

output[i] = input[i];

}

/* Note: Replace "for loop" with standard memset if possible.

*/

static void MD5_memset (POINTER output,

int value,

unsigned int len)

{

unsigned int i;

for (i = 0; i len; i++)

((char *)output)[i] = (char)value;

}

/* Digests a string and prints the result.

*/

char* MDString (char *string)

{

MD5_CTX context;

unsigned char digest[16];

char output1[32];

static char output[33]={""};

unsigned int len = strlen (string);

int i;

MD5Init (context);

MD5Update (context, (unsigned char*)string, len);

MD5Final (digest, context);

for (i = 0; i 16; i++)

{sprintf((output1[2*i]),"%02x",(unsigned char)digest[i]);

sprintf((output1[2*i+1]),"%02x",(unsigned char)(digest[i]4));

}

for(i=0;i32;i++)

output[i]=output1[i];

return output;

}

/* Digests a file and prints the result.

*/

char* MDFile (char *filename)

{ static char output[33]={""};

FILE *file;

MD5_CTX context;

int len;

unsigned char buffer[1024], digest[16];

int i;

char output1[32];

if ((file = fopen (filename, "rb")) == NULL)

{ printf ("%s can't be openedn", filename);

return 0;

}

else {

MD5Init (context);

while (len = fread (buffer, 1, 1024, file))

MD5Update (context, buffer, len);

MD5Final (digest, context);

fclose (file);

for (i = 0; i 16; i++)

{sprintf((output1[2*i]),"%02x",(unsigned char)digest[i]);

sprintf((output1[2*i+1]),"%02x",(unsigned char)(digest[i]4));

}

for(i=0;i32;i++)

output[i]=output1[i];

return output;

}

}

char* hmac_md5(char* text,char* key)

{

char digest[16];

char output1[32];

static char output[33]={""};

MD5_CTX context;

unsigned char k_ipad[65]; /* inner padding -

* key XORd with ipad

*/

unsigned char k_opad[65]; /* outer padding -

* key XORd with opad

*/

unsigned char tk[16];

int i;

int text_len = strlen (text);

int key_len=strlen(key);

/* if key is longer than 64 bytes reset it to key=MD5(key) */

if (key_len 64) {

MD5_CTX tctx;

MD5Init(tctx);

MD5Update(tctx,(unsigned char*) key, key_len);

MD5Final(tk, tctx);

key = (char*)tk;

key_len = 16;

}

/*

* the HMAC_MD5 transform looks like:

*

* MD5(K XOR opad, MD5(K XOR ipad, text))

*

* where K is an n byte key

* ipad is the byte 0x36 repeated 64 times

* opad is the byte 0x5c repeated 64 times

* and text is the data being protected

*/

/* start out by storing key in pads */

/*bzero( k_ipad, sizeof k_ipad);

bzero( k_opad, sizeof k_opad);

*/

for(i=0;i65;i++)

k_ipad[i]=(unsigned char)0;

for(i=0;i65;i++)

k_opad[i]=(unsigned char)0;

/*bcopy( key, k_ipad, key_len);

bcopy( key, k_opad, key_len);

*/

for(i=0;ikey_len;i++)

{k_ipad[i]=(unsigned char)key[i];

k_opad[i]=(unsigned char)key[i];

}

/* XOR key with ipad and opad values */

for (i=0; i64; i++) {

k_ipad[i] ^= 0x36;

k_opad[i] ^= 0x5c;

}

/*

* perform inner MD5

*/

MD5Init(context); /* init context for 1st

* pass */

MD5Update(context, k_ipad, 64); /* start with inner pad */

MD5Update(context, (unsigned char*)text, text_len); /* then text of datagram

*/

MD5Final((unsigned char*)digest, context); /* finish up 1st pass */

/*

* perform outer MD5

*/

MD5Init(context); /* init context for 2nd

* pass */

MD5Update(context, k_opad, 64); /* start with outer pad */

MD5Update(context,(unsigned char*) digest, 16); /* then results of 1st

* hash */

MD5Final((unsigned char*)digest, context); /* finish up 2nd pass */

for (i = 0; i 16; i++)

{sprintf((output1[2*i]),"%02x",(unsigned char)digest[i]);

sprintf((output1[2*i+1]),"%02x",(unsigned char)(digest[i]4));

}

for(i=0;i32;i++)

output[i]=output1[i];

return output;

}

上面是MD5用C来实现的方法

求正确的RSA加密解密算法C语言的,多谢。

//rsa.h

#include stdio.h

#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( m2 || n2 )

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; iz; i++ )

{

if( isPrime( i, z ) )

{

pset.set[ pset.size++ ] = i;

}

}

return pset.size;

}

// 名称:MakePairKey

// 功能:生成RSA公、私钥对

//  参数:uiP: 素数P; uiQ: 素数Q; uiD: 私钥d

// 返回:错误代码

unsigned int MakePairkey( unsigned int uiP, unsigned int uiQ, unsigned int uiD )

{

bool bFlag = true;

unsigned int i = 0, e;

unsigned int z = ( uiP-1 ) * ( uiQ-1 );

unsigned int d = pset.set[uiD];

//d=uiD;

if( !isPrime( z, d ) )

return ERROR_NOEACHPRIME;

for( i=2; iz; i++ )

{

if( (i*d)%z == 1 )

{

e = i;

bFlag = false;

}

}

if( bFlag )

return ERROR_NOPUBLICKEY;

if( (d*e)%z != 1 )

ERROR_GENERROR;

pairkey.d = d;

pairkey.e = e;

pairkey.n = uiP * uiQ;

return OK;

}

// 名称:GetPairKey

// 功能:对外提供接口,获得公、私钥对

//  参数:uiP: 素数P; uiQ: 素数Q; uiD: 私钥d

// 返回:

unsigned int GetPairKey( unsigned int d, unsigned int e )

{

d = pairkey.d;

e = pairkey.e;

return pairkey.n;

}

// 名称:GetPrivateKeyd

// 功能:对外提供接口,由用户选择ID得以私钥d

//  参数:iWhich: 用户选择私钥d的ID

// 返回:私钥d值

unsigned int GetPrivateKeyd( unsigned int iWhich )

{

if( pset.size = 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; imLength; i++ )

{

temInt = mw[i];

if( e!=0 )

{

for( j=1; je; j++ )

{

temInt = ( temInt * mw[i] ) % n;

}

}

else

{

temInt = 1;

}

cw[i] = (int)temInt;

}

}

// 名称:rsa_decrypt

// 功能:RSA解密运算

//  参数:n: 私钥n; d: 私钥d; cw: 密文; cLength: 密文长度; mw: 明文输出

// 返回:无

void rsa_decrypt( int n, int d, int *cw, int cLength, char *mw )

{

int i=0, j=-1;

__int64 temInt = 0;

for( i=0; icLength/4; ++i )

{

mw[i] = 0;

temInt = cw[i];

if( d != 0 )

{

for( j=1; jd; j++ )

{

temInt = (__int64)( temInt * cw[i] ) % n;

}

}

else

{

temInt = 1;

}

mw[i] = (char)temInt;

}

}

void outputkey()

{

printf("PublicKey(e,n): (%d,%d)\n",pairkey.e,pairkey.n);

printf("PrivateKey(d,n): (%d,%d)\n",pairkey.d,pairkey.n);

}

//main.c

// 工程:RSA

// 功能:RSA加、解密文件

//  作者:jlcss|ExpNIS

#include stdio.h

#include afxwin.h

#include math.h

#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( iFileLenMAX_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 PKCS#1在java中怎么实现?

楼主看看下面的代码是不是你所需要的,这是我原来用的时候收集的

import javax.crypto.Cipher;

import java.security.*;

import java.security.spec.RSAPublicKeySpec;

import java.security.spec.RSAPrivateKeySpec;

import java.security.spec.InvalidKeySpecException;

import java.security.interfaces.RSAPrivateKey;

import java.security.interfaces.RSAPublicKey;

import java.io.*;

import java.math.BigInteger;

/**

* RSA 工具类。提供加密,解密,生成密钥对等方法。

* 需要到下载bcprov-jdk14-123.jar。

* RSA加密原理概述

* RSA的安全性依赖于大数的分解,公钥和私钥都是两个大素数(大于100的十进制位)的函数。

* 据猜测,从一个密钥和密文推断出明文的难度等同于分解两个大素数的积

* ===================================================================

* (该算法的安全性未得到理论的证明)

* ===================================================================

* 密钥的产生:

* 1.选择两个大素数 p,q ,计算 n=p*q;

* 2.随机选择加密密钥 e ,要求 e 和 (p-1)*(q-1)互质

* 3.利用 Euclid 算法计算解密密钥 d , 使其满足 e*d = 1(mod(p-1)*(q-1)) (其中 n,d 也要互质)

* 4:至此得出公钥为 (n,e) 私钥为 (n,d)

* ===================================================================

* 加解密方法:

* 1.首先将要加密的信息 m(二进制表示) 分成等长的数据块 m1,m2,...,mi 块长 s(尽可能大) ,其中 2^sn

* 2:对应的密文是: ci = mi^e(mod n)

* 3:解密时作如下计算: mi = ci^d(mod n)

* ===================================================================

* RSA速度

* 由于进行的都是大数计算,使得RSA最快的情况也比DES慢上100倍,无论是软件还是硬件实现。

* 速度一直是RSA的缺陷。一般来说只用于少量数据加密。

* 文件名:RSAUtil.javabr

* @author 赵峰br

* 版本:1.0.1br

* 描述:本算法摘自网络,是对RSA算法的实现br

* 创建时间:2009-7-10 下午09:58:16br

* 文件描述:首先生成两个大素数,然后根据Euclid算法生成解密密钥br

*/

public class RSAUtil {

//密钥对

private KeyPair keyPair = null;

/**

* 初始化密钥对

*/

public RSAUtil(){

try {

this.keyPair = this.generateKeyPair();

} catch (Exception e) {

e.printStackTrace();

}

}

/**

* 生成密钥对

* @return KeyPair

* @throws Exception

*/

private KeyPair generateKeyPair() throws Exception {

try {

KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance("RSA",new org.bouncycastle.jce.provider.BouncyCastleProvider());

//这个值关系到块加密的大小,可以更改,但是不要太大,否则效率会低

final int KEY_SIZE = 1024;

keyPairGen.initialize(KEY_SIZE, new SecureRandom());

KeyPair keyPair = keyPairGen.genKeyPair();

return keyPair;

} catch (Exception e) {

throw new Exception(e.getMessage());

}

}

/**

* 生成公钥

* @param modulus

* @param publicExponent

* @return RSAPublicKey

* @throws Exception

*/

private RSAPublicKey generateRSAPublicKey(byte[] modulus, byte[] publicExponent) throws Exception {

KeyFactory keyFac = null;

try {

keyFac = KeyFactory.getInstance("RSA", new org.bouncycastle.jce.provider.BouncyCastleProvider());

} catch (NoSuchAlgorithmException ex) {

throw new Exception(ex.getMessage());

}

RSAPublicKeySpec pubKeySpec = new RSAPublicKeySpec(new BigInteger(modulus), new BigInteger(publicExponent));

try {

return (RSAPublicKey) keyFac.generatePublic(pubKeySpec);

} catch (InvalidKeySpecException ex) {

throw new Exception(ex.getMessage());

}

}

/**

* 生成私钥

* @param modulus

* @param privateExponent

* @return RSAPrivateKey

* @throws Exception

*/

private RSAPrivateKey generateRSAPrivateKey(byte[] modulus, byte[] privateExponent) throws Exception {

KeyFactory keyFac = null;

try {

keyFac = KeyFactory.getInstance("RSA", new org.bouncycastle.jce.provider.BouncyCastleProvider());

} catch (NoSuchAlgorithmException ex) {

throw new Exception(ex.getMessage());

}

RSAPrivateKeySpec priKeySpec = new RSAPrivateKeySpec(new BigInteger(modulus), new BigInteger(privateExponent));

try {

return (RSAPrivateKey) keyFac.generatePrivate(priKeySpec);

} catch (InvalidKeySpecException ex) {

throw new Exception(ex.getMessage());

}

}

/**

* 加密

* @param key 加密的密钥

* @param data 待加密的明文数据

* @return 加密后的数据

* @throws Exception

*/

public byte[] encrypt(Key key, byte[] data) throws Exception {

try {

Cipher cipher = Cipher.getInstance("RSA", new org.bouncycastle.jce.provider.BouncyCastleProvider());

cipher.init(Cipher.ENCRYPT_MODE, key);

// 获得加密块大小,如:加密前数据为128个byte,而key_size=1024 加密块大小为127 byte,加密后为128个byte;

// 因此共有2个加密块,第一个127 byte第二个为1个byte

int blockSize = cipher.getBlockSize();

// System.out.println("blockSize:"+blockSize);

int outputSize = cipher.getOutputSize(data.length);// 获得加密块加密后块大小

// System.out.println("加密块大小:"+outputSize);

int leavedSize = data.length % blockSize;

// System.out.println("leavedSize:"+leavedSize);

int blocksSize = leavedSize != 0 ? data.length / blockSize + 1 : data.length / blockSize;

byte[] raw = new byte[outputSize * blocksSize];

int i = 0;

while (data.length - i * blockSize 0) {

if (data.length - i * blockSize blockSize)

cipher.doFinal(data, i * blockSize, blockSize, raw, i * outputSize);

else

cipher.doFinal(data, i * blockSize, data.length - i * blockSize, raw, i * outputSize);

// 这里面doUpdate方法不可用,查看源代码后发现每次doUpdate后并没有什么实际动作除了把byte[]放到ByteArrayOutputStream中

// 而最后doFinal的时候才将所有的byte[]进行加密,可是到了此时加密块大小很可能已经超出了OutputSize所以只好用dofinal方法。

i++;

}

return raw;

} catch (Exception e) {

throw new Exception(e.getMessage());

}

}

/**

* 解密

* @param key 解密的密钥

* @param raw 已经加密的数据

* @return 解密后的明文

* @throws Exception

*/

@SuppressWarnings("static-access")

public byte[] decrypt(Key key, byte[] raw) throws Exception {

try {

Cipher cipher = Cipher.getInstance("RSA", new org.bouncycastle.jce.provider.BouncyCastleProvider());

cipher.init(cipher.DECRYPT_MODE, key);

int blockSize = cipher.getBlockSize();

ByteArrayOutputStream bout = new ByteArrayOutputStream(64);

int j = 0;

while (raw.length - j * blockSize 0) {

bout.write(cipher.doFinal(raw, j * blockSize, blockSize));

j++;

}

return bout.toByteArray();

} catch (Exception e) {

throw new Exception(e.getMessage());

}

}

/**

* 返回公钥

* @return

* @throws Exception

*/

public RSAPublicKey getRSAPublicKey() throws Exception{

//获取公钥

RSAPublicKey pubKey = (RSAPublicKey) keyPair.getPublic();

//获取公钥系数(字节数组形式)

byte[] pubModBytes = pubKey.getModulus().toByteArray();

//返回公钥公用指数(字节数组形式)

byte[] pubPubExpBytes = pubKey.getPublicExponent().toByteArray();

//生成公钥

RSAPublicKey recoveryPubKey = this.generateRSAPublicKey(pubModBytes,pubPubExpBytes);

return recoveryPubKey;

}

/**

* 获取私钥

* @return

* @throws Exception

*/

public RSAPrivateKey getRSAPrivateKey() throws Exception{

// 获取私钥

RSAPrivateKey priKey = (RSAPrivateKey) keyPair.getPrivate();

// 返回私钥系数(字节数组形式)

byte[] priModBytes = priKey.getModulus().toByteArray();

// 返回私钥专用指数(字节数组形式)

byte[] priPriExpBytes = priKey.getPrivateExponent().toByteArray();

// 生成私钥

RSAPrivateKey recoveryPriKey = this.generateRSAPrivateKey(priModBytes,priPriExpBytes);

return recoveryPriKey;

}

/**

* 测试

* @param args

* @throws Exception

*/

public static void main(String[] args) throws Exception {

RSAUtil rsa = new RSAUtil();

String str = "天龙八部、神雕侠侣、射雕英雄传白马啸西风";

RSAPublicKey pubKey = rsa.getRSAPublicKey();

RSAPrivateKey priKey = rsa.getRSAPrivateKey();

// System.out.println("加密后==" + new String(rsa.encrypt(pubKey,str.getBytes())));

String mw = new String(rsa.encrypt(pubKey, str.getBytes()));

System.out.println("加密后:"+mw);

// System.out.println("解密后:");

System.out.println("解密后==" + new String(rsa.decrypt(priKey,rsa.encrypt(pubKey,str.getBytes()))));

}

}

如何用C语言实现RSA算法

RSA算法它是第一个既能用于数据加密也能用于数字签名的算法。它易于理解和操作,也很流行。算法的名字以发明者的名字

命名:Ron Rivest, Adi Shamir 和Leonard

Adleman。但RSA的安全性一直未能得到理论上的证明。它经历了各种攻击,至今未被完全攻破。

一、RSA算法 :

首先, 找出三个数, p, q, r,

其中 p, q 是两个相异的质数, r 是与 (p-1)(q-1) 互质的数

p, q, r 这三个数便是 private key

接著, 找出 m, 使得 rm == 1 mod (p-1)(q-1)

这个 m 一定存在, 因为 r 与 (p-1)(q-1) 互质, 用辗转相除法就可以得到了

再来, 计算 n = pq

m, n 这两个数便是 public key

编码过程是, 若资料为 a, 将其看成是一个大整数, 假设 a n

如果 a = n 的话, 就将 a 表成 s 进位 (s = n, 通常取 s = 2^t),

则每一位数均小於 n, 然後分段编码

接下来, 计算 b == a^m mod n, (0 = b n),

b 就是编码後的资料

解码的过程是, 计算 c == b^r mod pq (0 = c pq),

於是乎, 解码完毕 等会会证明 c 和 a 其实是相等的 :)

如果第三者进行窃听时, 他会得到几个数: m, n(=pq), b

他如果要解码的话, 必须想办法得到 r

所以, 他必须先对 n 作质因数分解

要防止他分解, 最有效的方法是找两个非常的大质数 p, q,

使第三者作因数分解时发生困难

定理

若 p, q 是相异质数, rm == 1 mod (p-1)(q-1),

a 是任意一个正整数, b == a^m mod pq, c == b^r mod pq,

则 c == a mod pq

证明的过程, 会用到费马小定理, 叙述如下:

m 是任一质数, n 是任一整数, 则 n^m == n mod m

(换另一句话说, 如果 n 和 m 互质, 则 n^(m-1) == 1 mod m)

运用一些基本的群论的知识, 就可以很容易地证出费马小定理的

证明

因为 rm == 1 mod (p-1)(q-1), 所以 rm = k(p-1)(q-1) + 1, 其中 k 是整数

因为在 modulo 中是 preserve 乘法的

(x == y mod z and u == v mod z = xu == yv mod z),

所以, c == b^r == (a^m)^r == a^(rm) == a^(k(p-1)(q-1)+1) mod pq

1. 如果 a 不是 p 的倍数, 也不是 q 的倍数时,

则 a^(p-1) == 1 mod p (费马小定理) = a^(k(p-1)(q-1)) == 1 mod p

a^(q-1) == 1 mod q (费马小定理) = a^(k(p-1)(q-1)) == 1 mod q

所以 p, q 均能整除 a^(k(p-1)(q-1)) - 1 = pq | a^(k(p-1)(q-1)) - 1

即 a^(k(p-1)(q-1)) == 1 mod pq

= c == a^(k(p-1)(q-1)+1) == a mod pq

2. 如果 a 是 p 的倍数, 但不是 q 的倍数时,

则 a^(q-1) == 1 mod q (费马小定理)

= a^(k(p-1)(q-1)) == 1 mod q

= c == a^(k(p-1)(q-1)+1) == a mod q

= q | c - a

因 p | a

= c == a^(k(p-1)(q-1)+1) == 0 mod p

= p | c - a

所以, pq | c - a = c == a mod pq

3. 如果 a 是 q 的倍数, 但不是 p 的倍数时, 证明同上

4. 如果 a 同时是 p 和 q 的倍数时,

则 pq | a

= c == a^(k(p-1)(q-1)+1) == 0 mod pq

= pq | c - a

= c == a mod pq

Q.E.D.

这个定理说明 a 经过编码为 b 再经过解码为 c 时, a == c mod n (n = pq)

但我们在做编码解码时, 限制 0 = a n, 0 = c n,

所以这就是说 a 等於 c, 所以这个过程确实能做到编码解码的功能

二、RSA 的安全性

RSA的安全性依赖于大数分解,但是否等同于大数分解一直未能得到理论上的证明,因为没有证明破解

RSA就一定需要作大数分解。假设存在一种无须分解大数的算法,那它肯定可以修改成为大数分解算法。目前, RSA

的一些变种算法已被证明等价于大数分解。不管怎样,分解n是最显然的攻击方法。现在,人们已能分解多个十进制位的大素数。因此,模数n

必须选大一些,因具体适用情况而定。

三、RSA的速度

由于进行的都是大数计算,使得RSA最快的情况也比DES慢上倍,无论是软件还是硬件实现。速度一直是RSA的缺陷。一般来说只用于少量数据加密。

四、RSA的选择密文攻击

RSA在选择密文攻击面前很脆弱。一般攻击者是将某一信息作一下伪装( Blind),让拥有私钥的实体签署。然后,经过计算就可得到它所想要的信息。实际上,攻击利用的都是同一个弱点,即存在这样一个事实:乘幂保留了输入的乘法结构:

( XM )^d = X^d *M^d mod n

前面已经提到,这个固有的问题来自于公钥密码系统的最有用的特征--每个人都能使用公钥。但从算法上无法解决这一问题,主要措施有两条:一条是采用好的公

钥协议,保证工作过程中实体不对其他实体任意产生的信息解密,不对自己一无所知的信息签名;另一条是决不对陌生人送来的随机文档签名,签名时首先使用

One-Way HashFunction 对文档作HASH处理,或同时使用不同的签名算法。在中提到了几种不同类型的攻击方法。

五、RSA的公共模数攻击

若系统中共有一个模数,只是不同的人拥有不同的e和d,系统将是危险的。最普遍的情况是同一信息用不同的公钥加密,这些公钥共模而且互质,那末该信息无需私钥就可得到恢复。设P为信息明文,两个加密密钥为e1和e2,公共模数是n,则:

C1 = P^e1 mod n

C2 = P^e2 mod n

密码分析者知道n、e1、e2、C1和C2,就能得到P。

因为e1和e2互质,故用Euclidean算法能找到r和s,满足:

r * e1 + s * e2 = 1

假设r为负数,需再用Euclidean算法计算C1^(-1),则

( C1^(-1) )^(-r) * C2^s = P mod n

另外,还有其它几种利用公共模数攻击的方法。总之,如果知道给定模数的一对e和d,一是有利于攻击者分解模数,一是有利于攻击者计算出其它成对的e’和d’,而无需分解模数。解决办法只有一个,那就是不要共享模数n。

RSA的小指数攻击。 有一种提高 RSA速度的建议是使公钥e取较小的值,这样会使加密变得易于实现,速度有

所提高。但这样作是不安全的,对付办法就是e和d都取较大的值。

RSA算法是

第一个能同时用于加密和数字签名的算法,也易于理解和操作。RSA是被研究得最广泛的公钥算法,从提出到现在已近二十年,经历了各种攻击的考验,逐渐为人

们接受,普遍认为是目前最优秀的公钥方案之一。RSA的安全性依赖于大数的因子分解,但并没有从理论上证明破译RSA的难度与大数分解难度等价。即RSA

的重大缺陷是无法从理论上把握它的保密性能

如何,而且密码学界多数人士倾向于因子分解不是NPC问题。

RSA的缺点主要有:A)产生密钥很麻烦,受到素数产生技术的限制,因而难以做到一次一密。B)分组长度太大,为保证安全性,n 至少也要 600

bits

以上,使运算代价很高,尤其是速度较慢,较对称密码算法慢几个数量级;且随着大数分解技术的发展,这个长度还在增加,不利于数据格式的标准化。目

前,SET( Secure Electronic Transaction )协议中要求CA采用比特长的密钥,其他实体使用比特的密钥。

C语言实现

#include stdio.h

int candp(int a,int b,int c)

{ int r=1;

b=b+1;

while(b!=1)

{

r=r*a;

r=r%c;

b--;

}

printf("%d\n",r);

return r;

}

void main()

{

int p,q,e,d,m,n,t,c,r;

char s;

printf("please input the p,q: ");

scanf("%d%d",p,q);

n=p*q;

printf("the n is %3d\n",n);

t=(p-1)*(q-1);

printf("the t is %3d\n",t);

printf("please input the e: ");

scanf("%d",e);

if(e1||et)

{

printf("e is error,please input again: ");

scanf("%d",e);

}

d=1;

while(((e*d)%t)!=1) d++;

printf("then caculate out that the d is %d\n",d);

printf("the cipher please input 1\n");

printf("the plain please input 2\n");

scanf("%d",r);

switch(r)

{

case 1: printf("input the m: "); /*输入要加密的明文数字*/

scanf("%d",m);

c=candp(m,e,n);

printf("the cipher is %d\n",c);break;

case 2: printf("input the c: "); /*输入要解密的密文数字*/

scanf("%d",c);

m=candp(c,d,n);

printf("the cipher is %d\n",m);break;

}

getch();

}

关于rsa数字签名源代码和rsa签名算法采用了什么密码算法的介绍到此就结束了,不知道你从中找到你需要的信息了吗 ?如果你还想了解更多这方面的信息,记得收藏关注本站。

版权说明:如非注明,本站文章均为 AH站长 原创,转载请注明出处和附带本文链接;

本文地址:http://ahzz.com.cn/post/14074.html


取消回复欢迎 发表评论:

分享到

温馨提示

下载成功了么?或者链接失效了?

联系我们反馈

立即下载