㈠ 有個實驗,是編程實現基於RSA演算法的數字簽名,求c語言代碼啊,c++的也行。
親,這是rails吧,
㈡ 如何用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 是整數
因為在 molo 中是 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(e<1||e>t)
{
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的演算法,C語言實現的~!編程高手進啊~!救命啊~!
看你催就倉促寫了個,自我感覺寫的不是很好,但是能用了。數據只能是大寫字母組成的字元串。
加密的時候,輸入Y,然後輸入要加密的文本(大寫字母)
解密的時候,輸入N,然後輸入一個整數n表示密文的個數,然後n個整數表示加密時候得到的密文。
/*RSA
algorithm
*/
#include
<stdio.h>
#include
<string.h>
#include
<stdlib.h>
#define
MM
7081
#define
KK
1789
#define
PHIM
6912
#define
PP
85
typedef
char
strtype[10000];
int
len;
long
nume[10000];
int
change[126];
char
antichange[37];
void
initialize()
{
int
i;
char
c;
for
(i
=
11,
c
=
'A';
c
<=
'Z';
c
++,
i
++)
{
change[c]
=
i;
antichange[i]
=
c;
}
}
void
changetonum(strtype
str)
{
int
l
=
strlen(str),
i;
len
=
0;
memset(nume,
0,
sizeof(nume));
for
(i
=
0;
i
<
l;
i
++)
{
nume[len]
=
nume[len]
*
100
+
change[str[i]];
if
(i
%
2
==
1)
len
++;
}
if
(i
%
2
!=
0)
len
++;
}
long
binamod(long
numb,
long
k)
{
if
(k
==
0)
return
1;
long
curr
=
binamod
(numb,
k
/
2);
if
(k
%
2
==
0)
return
curr
*
curr
%
MM;
else
return
(curr
*
curr)
%
MM
*
numb
%
MM;
}
long
encode(long
numb)
{
return
binamod(numb,
KK);
}
long
decode(long
numb)
{
return
binamod(numb,
PP);
}
main()
{
strtype
str;
int
i,
a1,
a2;
long
curr;
initialize();
puts("Input
'Y'
if
encoding,
otherwise
input
'N':");
gets(str);
if
(str[0]
==
'Y')
{
gets(str);
changetonum(str);
printf("encoded:
");
for
(i
=
0;
i
<
len;
i
++)
{
if
(i)
putchar('-');
printf("
%ld
",
encode(nume[i]));
}
putchar('\n');
}
else
{
scanf("%d",
&len);
for
(i
=
0;
i
<
len;
i
++)
{
scanf("%ld",
&curr);
curr
=
decode(curr);
a1
=
curr
/
100;
a2
=
curr
%
100;
printf("decoded:
");
if
(a1
!=
0)
putchar(antichange[a1]);
if
(a2
!=
0)
putchar(antichange[a2]);
}
putchar('\n');
}
putchar('\n');
system("PAUSE");
return
0;
}
測試:
輸入:
Y
FERMAT
輸出:
encoded:
5192
-
2604
-
4222
輸入
N
3
5192
2604
4222
輸出
decoded:
FERMAT
㈣ rsa演算法c語言實現
程序修改如下:
(主要是你的循環寫的不對,輸入的字元應該-'0'才能與正常的數字對應)
#include<stdio.h>
#include<math.h>
int
candp(int
a,int
b,int
c)
{int
r=1;
int
s;
int
i=1;
for(i=1;i<=b;i++)r=r*a;
printf("%d\
",r);
s=r%c;
printf("%d\
",s);
return
s;}
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;
t=(p-1)*(q-1);
printf("the
n
is
%12d\
",n);
printf("please
input
the
e:");
scanf("%d",&e);
while(e<1||e>n)
//此處修改為while循環
{
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\
",d);
printf("the
cipher
please
input
1\
");
printf("the
plain
please
input
2\
");
scanf("%c",&s);
while((s-'0')!=1&&(s-'0')!=2)
//消除後面的getchar()
此處增加while循環注意括弧內的字元
{scanf("%c",&s);}
switch(s-'0')
{
case
1:printf("intput
the
m:");
scanf("%d",&m);
c=candp(m,e,n);
printf("the
plain
is
%d\
",c);break;
case
2:printf("input
the
c:");
scanf("%d",&c);
m=candp(c,d,n);
printf("the
cipher
is
%8d\
",m);
break;
}
}
㈤ 如何用C語言來使用openssl rsa進行公鑰加密,已有公鑰和明文
1. 本程序使用2048位密鑰對,每次加密時,原始數據的最大長度為245位元組,加密後的密文長度為256位元組.(採用打PADDING 的加密方式)
2. 如果所加密數據長度大於245位元組,請分多次加密,後將密文按順序存儲;解密時,每次讀取256位元組,進行解密,將解密後的數據依次按順序存儲,即可還原原始數據.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <openssl/rsa.h>
#include <openssl/pem.h>
#include <openssl/err.h>
#define OPENSSLKEY "test.key"
#define PUBLICKEY "test_pub.key"
#define BUFFSIZE 1024
char *my_encrypt(char *str, char *path_key); //加密
char *my_decrypt(char *str, char *path_key); //解密
int main(void)
{
char *source = "i like dancing !!!";
char *ptf_en, *ptf_de;
printf("source is :%s\n", source);
//1.加密
ptf_en = my_encrypt(source, PUBLICKEY);
if (ptf_en == NULL){
return 0;
}else{
printf("ptf_en is :%s\n", ptf_en);
}
//2.解密
ptf_de = my_decrypt(ptf_en, OPENSSLKEY);
if (ptf_de == NULL){
return 0;
}else{
printf("ptf_de is :%s\n", ptf_de);
}
if(ptf_en) free(ptf_en);
if(ptf_de) free(ptf_de);
return 0;
}
//加密
char *my_encrypt(char *str, char *path_key)
{
char *p_en = NULL;
RSA *p_rsa = NULL;
FILE *file = NULL;
int lenth = 0; //flen為源文件長度, rsa_len為秘鑰長度
//1.打開秘鑰文件
if((file = fopen(path_key, "rb")) == NULL)
{
perror("fopen() error 111111111 ");
goto End;
}
//2.從公鑰中獲取 加密的秘鑰
if((p_rsa = PEM_read_RSA_PUBKEY(file, NULL,NULL,NULL )) == NULL)
{
ERR_print_errors_fp(stdout);
goto End;
}
lenth = strlen(str);
p_en = (char *)malloc(256);
if(!p_en)
{
perror("malloc() error 2222222222");
goto End;
}
memset(p_en, 0, 256);
//5.對內容進行加密
if(RSA_public_encrypt(lenth, (unsigned char*)str, (unsigned char*)p_en, p_rsa, RSA_PKCS1_PADDING) < 0)
{
perror("RSA_public_encrypt() error 2222222222");
goto End;
}
End:
//6.釋放秘鑰空間, 關閉文件
if(p_rsa) RSA_free(p_rsa);
if(file) fclose(file);
return p_en;
}
//解密
char *my_decrypt(char *str, char *path_key)
{
char *p_de = NULL;
RSA *p_rsa = NULL;
FILE *file = NULL;
//1.打開秘鑰文件
file = fopen(path_key, "rb");
if(!file)
{
perror("fopen() error 22222222222");
goto End;
}
//2.從私鑰中獲取 解密的秘鑰
if((p_rsa = PEM_read_RSAPrivateKey(file, NULL,NULL,NULL )) == NULL)
{
ERR_print_errors_fp(stdout);
goto End;
}
p_de = (char *)malloc(245);
if(!p_de)
{
perror("malloc() error ");
goto End;
}
memset(p_de, 0, 245);
//5.對內容進行加密
if(RSA_private_decrypt(256, (unsigned char*)str, (unsigned char*)p_de, p_rsa, RSA_PKCS1_PADDING) < 0)
{
perror("RSA_public_encrypt() error ");
goto End;
}
End:
//6.釋放秘鑰空間, 關閉文件
if(p_rsa) RSA_free(p_rsa);
if(file) fclose(file);
return p_de;
}
㈥ 如何用C語言實現RSA演算法
上學期交的作業,已通過老師在運行時間上的測試
#include <stdio.h>
#include <stdlib.h>
unsigned long prime1,prime2,ee;
unsigned long *kzojld(unsigned long p,unsigned long q) //擴展歐幾里得演算法求模逆
{
unsigned long i=0,a=1,b=0,c=0,d=1,temp,mid,ni[2];
mid=p;
while(mid!=1)
{
while(p>q)
{p=p-q; mid=p;i++;}
a=c*(-1)*i+a;b=d*(-1)*i+b;
temp=a;a=c;c=temp;
temp=b;b=d;d=temp;
temp=p;p=q;q=temp;
i=0;
}
ni[0]=c;ni[1]=d;
return(ni);
}
unsigned long momi(unsigned long a,unsigned long b,unsigned long p) //模冪演算法
{
unsigned long c;
c=1;
if(a>p) a=a%p;
if(b>p) b=b%(p-1);
while(b!=0)
{
while(b%2==0)
{
b=b/2;
a=(a*a)%p;
}
b=b-1;
c=(a*c)%p;
}
return(c);
}
void RSAjiami() //RSA加密函數
{
unsigned long c1,c2;
unsigned long m,n,c;
n=prime1*prime2;
system("cls");
printf("Please input the message:\n");
scanf("%lu",&m);getchar();
c=momi(m,ee,n);
printf("The cipher is:%lu",c);
return;
}
void RSAjiemi() //RSA解密函數
{
unsigned long m1,m2,e,d,*ni;
unsigned long c,n,m,o;
o=(prime1-1)*(prime2-1);
n=prime1*prime2;
system("cls");
printf("Please input the cipher:\n");
scanf("%lu",&c);getchar();
ni=kzojld(ee,o);
d=ni[0];
m=momi(c,d,n);
printf("The original message is:%lu",m);
return;
}
void main()
{ unsigned long m;
char cho;
printf("Please input the two prime you want to use:\n");
printf("P=");scanf("%lu",&prime1);getchar();
printf("Q=");scanf("%lu",&prime2);getchar();
printf("E=");scanf("%lu",&ee);getchar();
if(prime1<prime2)
{m=prime1;prime1=prime2;prime2=m;}
while(1)
{
system("cls");
printf("\t*******RSA密碼系統*******\n");
printf("Please select what do you want to do:\n");
printf("1.Encrpt.\n");
printf("2.Decrpt.\n");
printf("3.Exit.\n");
printf("Your choice:");
scanf("%c",&cho);getchar();
switch(cho)
{ case '1':RSAjiami();break;
case '2':RSAjiemi();break;
case '3':exit(0);
default:printf("Error input.\n");break;
}
getchar();
}
}
㈦ 急急急!跪求RSA演算法加密 C語言 最簡單的就可以 要求可以直接運行出界面,請附帶界面的
http://hi..com/rankabc/item/47340498e5542af61b49df1c
㈧ windows 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,
使第三者作因數分解時發生困難
㈨ 求用C語言編寫程序RSA演算法
這個是我幫個朋友寫的,寫的時候發現其實這個沒那麼復雜,不過,時間復雜度要高於那些成型了的,為人所熟知的RSA演算法的其他語言實現.
#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",r);
return r;
}
void main()
{
int p,q,e,d,m,n,t,c,r;
char s;
{printf("input the p:\n");<br/> scanf("%d\n",&p);<br/> printf("input the q:\n");<br/> scanf("%d%d\n",&p); <br/> n=p*q;<br/> printf("so,the n is %3d\n",n);<br/> t=(p-1)*(q-1);<br/> printf("so,the t is %3d\n",t);<br/> printf("please intput the e:\n");<br/> scanf("%d",&e);<br/> if(e<1||e>t)<br/> {printf("e is error,please input again;");<br/> scanf("%d",&e);}
d=1;
while (((e*d)%t)!=1) d++;
printf("then caculate out that the d is %5d",d);
printf("if you want to konw the cipher please input 1;\n if you want to konw the plain please input 2;\n");
scanf("%d",&r);
if(r==1)
{
printf("input the m :" );/*輸入要加密的明文數字*/
scanf("%d\n",&m);
c=candp(m,e,n);
printf("so ,the cipher is %4d",c);}
if(r==2)
{
printf("input the c :" );/*輸入要解密的密文數字*/
scanf("%d\n",&c);
m=candp(c,d,n);
printf("so ,the cipher is %4d\n",m);
printf("do you want to use this programe:Yes or No");
scanf("%s",&s);
}while(s=='Y');
}
}