Ⅰ RSA加密原理
RSA加密是一種非對稱加密。可以在不直接傳遞密鑰的情況下,完成解密。這能夠確保信息的安全性,避免了直接傳遞密鑰所造成的被破解的風險。是由一對密鑰來進行加解密的過程,分別稱為公鑰和私鑰。公鑰加密--私鑰解密,私鑰加密--公鑰解密
在 整數 中, 離散對數 是一種基於 同餘 運算和 原根 的一種 對數 運算。而在實數中對數的定義 log b a 是指對於給定的 a 和 b ,有一個數 x ,使得 b x = a 。相同地在任何群 G 中可為所有整數 k 定義一個冪數為 b K ,而 離散對數 log b a 是指使得 b K = a 的整數 k 。
當3為17的 原根 時,我們會發現一個規律
對 正整數 n,歐拉函數是小於或等於n的正整數中與n 互質 的數的數目(因此φ(1)=1)。有以下幾個特點
服務端根據生成一個隨機數15,根據 3 15 mod 17 計算出6,服務端將6傳遞給客戶端,客戶端生成一個隨機數13,根據 3 13 mod 17 計算出12後,將12再傳回給服務端,客戶端收到服務端傳遞的6後,根據 6 13 mod 17 計算出 10 ,服務端收到客戶端傳遞的12後,根據 12 15 mod 17 計算出 10 ,我們會發現我們通過 迪菲赫爾曼密鑰交換 將 10 進行了加密傳遞
說明:
安全性:
除了 公鑰 用到 n 和 e ,其餘的4個數字是 不公開 的(p1、p2、φ(n)、d)
目前破解RSA得到的方式如下:
缺點
RSA加密 效率不高 ,因為是純粹的數學演算法,大數據不適合RSA加密,所以我們在加密大數據的時候,我們先用 對稱加密 演算法加密大數據得到 KEY ,然後再用 RSA 加密 KEY ,再把大數據和KEY一起進行傳遞
因為Mac系統內置了OpenSSL(開源加密庫),所以我們開源直接在終端進行RSA加密解密
生成RSA私鑰,密鑰名為private.pem,密鑰長度為1024bit
因為在iOS中是無法使用 .pem 文件進行加密和解密的,需要進行下面幾個步驟
生成一個10年期限的crt證書
crt證書格式轉換成der證書
Ⅱ RSA的公鑰和私鑰到底哪個才是用來加密和哪個用來解密
我們來回顧一下RSA的加密演算法。我們從公鑰加密演算法和簽名演算法的定義出發,用比較規范的語言來描述這一演算法。
RSA公鑰加密體制包含如下3個演算法:KeyGen(密鑰生成演算法),Encrypt(加密演算法)以及Decrypt(解密演算法)。
(PK, SK)\leftarrow KeyGen(\lambda)。密鑰生成演算法以安全常數\lambda作為輸入,輸出一個公鑰PK,和一個私鑰SK。安全常數用於確定這個加密演算法的安全性有多高,一般以加密演算法使用的質數p的大小有關。\lambda越大,質數p一般越大,保證體制有更高的安全性。在RSA中,密鑰生成演算法如下:演算法首先隨機產生兩個不同大質數p和q,計算N=pq。隨後,演算法計算歐拉函數\varphi(N)=(p-1)(q-1)。接下來,演算法隨機選擇一個小於\varphi(N)的整數e,並計算e關於\varphi(N)的模反元素d。最後,公鑰為PK=(N, e),私鑰為SK=(N, d)。
CT \leftarrow Encrypt(PK,M)。加密演算法以公鑰PK和待加密的消息M作為輸入,輸出密文CT。在RSA中,加密演算法如下:演算法直接輸出密文為CT=M^e \mod \varphi(N)
M \leftarrow Decrypt(SK,CT)。解密演算法以私鑰SK和密文CT作為輸入,輸出消息M。在RSA中,解密演算法如下:演算法直接輸出明文為M=CT^d \mod \varphi(N)。由於e和d在\varphi(N)下互逆,因此我們有:CT^d=M^{ed}=M\mod \varphi(N)
所以,從演算法描述中我們也可以看出:公鑰用於對數據進行加密,私鑰用於對數據進行解密。當然了,這個也可以很直觀的理解:公鑰就是公開的密鑰,其公開了大家才能用它來加密數據。私鑰是私有的密鑰,誰有這個密鑰才能夠解密密文。否則大家都能看到私鑰,就都能解密,那不就亂套了。
=================分割線=================
我們再來回顧一下RSA簽名體制。簽名體制同樣包含3個演算法:KeyGen(密鑰生成演算法),Sign(簽名演算法),Verify(驗證演算法)。
(PK,SK) \leftarrow KeyGen(\lambda)。密鑰生成演算法同樣以安全常數\lambda作為輸入,輸出一個公鑰PK和一個私鑰SK。在RSA簽名中,密鑰生成演算法與加密演算法完全相同。
\sigma \leftarrow Sign(SK,M)。簽名演算法以私鑰SK和待簽名的消息M作為輸入,輸出簽名\sigma。在RSA簽名中,簽名演算法直接輸出簽名為\sigma = M^d \mod \varphi(N)。注意,簽名演算法和RSA加密體制中的解密演算法非常像。
b \leftarrow Verify(PK,\sigma,M)。驗證演算法以公鑰PK,簽名\sigma以及消息M作為輸入,輸出一個比特值b。b=1意味著驗證通過。b=0意味著驗證不通過。在RSA簽名中,驗證演算法首先計算M'=\sigma^e \mod \varphi(N),隨後對比M'與M,如果相等,則輸出b=1,否則輸出b=0。注意:驗證演算法和RSA加密體制中的加密演算法非常像。
所以,在簽名演算法中,私鑰用於對數據進行簽名,公鑰用於對簽名進行驗證。這也可以直觀地進行理解:對一個文件簽名,當然要用私鑰,因為我們希望只有自己才能完成簽字。驗證過程當然希望所有人都能夠執行,大家看到簽名都能通過驗證證明確實是我自己簽的。
=================分割線=================
那麼,為什麼題主問這么一個問題呢?我們可以看到,RSA的加密/驗證,解密/簽字過程太像了。同時,RSA體制本身就是對稱的:如果我們反過來把e看成私鑰,d看成公鑰,這個體制也能很好的執行。我想正是由於這個原因,題主在學習RSA體制的時候才會出現這種混亂。那麼解決方法是什麼呢?建議題主可以學習一下其他的公鑰加密體制以及簽名體制。其他的體制是沒有這種對稱性質的。舉例來說,公鑰加密體制的話可以看一看ElGamal加密,以及更安全的Cramer-Shoup加密。簽名體制的話可以進一步看看ElGamal簽名,甚至是BLS簽名,這些體制可能能夠幫助題主更好的弄清加密和簽名之間的區別和潛在的聯系。
至於題主問的加密和簽名是怎麼結合的。這種體制叫做簽密方案(SignCrypt),RSA中,這種簽密方案看起來特別特別像,很容易引起混亂。在此我不太想詳細介紹RSA中的加密與簽字結合的方案。我想提醒題主的是,加密與簽字結合時,兩套公私鑰是不同的。
Ⅲ 緇欏嚭p銆乹銆乪銆丮錛岃捐′竴涓猂SA綆楁硶錛屾眰鍏閽ワ紝縐侀掗錛屽苟涓斿埄鐢≧SA綆楁硶鍔犲瘑鍜岃В瀵嗭紵
閭f垜緇欎綘瑙i噴涓婻SA鍚э紝灝介噺璁╀綘鐪嬫噦錛
*RSA鏄闈炲圭О鍔犲瘑浣撶郴錛屼篃灝辨槸璇村姞瀵嗙敤涓涓鍏閽ワ紝瑙e瘑鐢ㄤ竴涓縐侀掗錛岃繖2涓瀵嗛掗涓嶅悓錛岃繖鐐歸潪甯擱潪甯擱噸瑕併
鍏跺疄RSA闈炲父綆媧侊紝浣嗗緢緹
嫻佺▼
1錛屽繪壘2涓澶х殑緔犳暟p錛宷 n=p*q=33 N=錛坧-1錛*錛坬-1錛=20
鍏閽e涓鑸鏄3 縐侀掗d瑕侀氳繃鍏閽e鍘葷畻鍑烘潵
e*d=1(mod N) 灝辨槸璇磂鍜宒鐨勪箻縐妯N寰1 涔熷氨鏄痚鍜宒鍏充簬妯N浜掍負閫嗗厓
3*7=1錛坢od 20錛 鍙鐭d=7
鍔犲瘑鐨勬槑鏂囪句負M 鍔犲瘑鍚庣殑瀵嗘枃璁句負c
鍔犲瘑榪囩▼錛欳=M^e(mod n)
瑙e瘑榪囩▼錛歁=C^d(mod n)
涓句釜鍏蜂綋鐨勪緥瀛 鍋囧侻=2
鍔犲瘑榪囩▼錛欳=2^3(mod 33)=8(mod 33)
瑙e瘑榪囩▼錛歁=8^7(mod 33)=2097152(mod 33)=2(mod 33) 鍙浠ョ湅鍑哄拰鍜屾湰鏉ョ殑鏄庢枃鏄鐩稿悓鐨勩
鍘熺悊鍙浠ョ悊瑙d負 M=M^(ed) (mod n)
鏈渚嬩腑 e*d=21 涔熷氨鏄鏄疢^21嬈℃柟絳変簬M
RSA榪欎釜鐗規ф槸鏁拌轟腑鐨勮垂椹瀹氱悊鎺ㄥ嚭鐨
鍦ㄨ茶茬粏鑺 姣斿傛ゼ涓誨姞瀵嗙殑鏄26鐨勫瓧姣 灝卞綋鏄庢枃鐨勫兼槸浠1鍒26
灝辨嬁n=33璇村惂 鍔犲瘑鍚庣殑瀵嗘枃鐨勫兼槸1鍒33 榪欏緢姝e父
浣嗘槸瑙e瘑鍚 涓瀹氬拰鏄庢枃鐨勫肩浉鍚 涔熷氨鏄1鍒26
瀹為檯鎯呭喌涓 鍏閽e鏄鍏寮鐨 縐侀掗d鏄淇濆瘑鐨
姣斿傜敳瑕佺粰涔欏彂涓涓滆タ 涔欑殑鍏閽ョ敱浜庢槸鍏寮鐨 鎵浠ョ敳鐭ラ亾 浣嗙敳涓嶇煡閬撲箼鐨勭侀掗
鐢插厛鐢ㄤ箼鐨勫叕閽ュ姞瀵 涔嬪悗 榪欎釜瀵嗘枃鍙鑳界敤涔欑殑縐侀掗 鐢變簬涔欑殑縐侀掗鏄淇濆瘑鐨 鍙鏈変粬鑷宸辯煡閬 鎵浠ヤ繚璇佷簡瀹夊叏
RSA鏈澶х殑瀹夊叏闂棰樻槸 n鐨勫垎瑙 鍙瑕佹妸n鍒嗚В涓簆*q 鍒橬=錛坧-1錛夛紙q-1錛
鏍規嵁 e*d=1錛坢od N錛 灝卞彲浠ラ氳繃e綆楀嚭d 閭d箞縐侀掗閮借浜虹畻鍑烘潵浜 涔熷氨娌″畨鍏ㄦц岃█浜
涓嶈繃鍙鎯滅殑鏄 澶ф暟鍒嗚В鏄涓涓鍗曞悜鐨勫嚱鏁 浣犵畻鐭ラ亾p錛宷綆梟寰堝規槗錛屼絾鏄鐭ラ亾n綆楀嚭p錛宷鐩稿綋闅
寮鴻皟涓鍙 n鏄鍔犲瘑瑙e瘑鐢ㄧ殑 N鏄鐭ラ亾e綆梔鐨
妤間富涔熸病璇翠綘瑕佸共鍢 鎯崇湅鎳傚氨榪欎箞澶
濡傛灉瑕佸疄鐜拌繖涓綆楁硶錛
蹇呴』鐭ラ亾2鐐癸細
1.p錛宷榪欎釜涓や釜澶х礌鏁扮殑鐢熸垚錛岃繖鐗墊壇鍒扮礌鎬ф楠岋紝鏁拌轟腑鏄涓絝犵殑鍐呭癸紝娌℃硶鍜屼綘灞曞紑
2.鍙栨ā榪愮畻錛岀敱浜庡姞瀵嗚В瀵嗚繃紼嬪彲鑳藉彇涓涓鏁扮殑鍑犲嶮嬈℃柟鐨勬ā鏁幫紝鎵浠ヨ繖涓蹇呴』鐢ㄧ畝渚跨殑綆楁硶鏉ュ寲瑙e嶆潅搴︼紝涔熷氨鏄妯¢噸澶嶅鉤鏂圭畻娉曘
濡傛灉瑕佺紪紼嬩腑浣跨敤錛屽お瀹規槗浜
鍘諱笅涓猟ll
鍦╦ava涓 鐩存帴鏈夊彲鐢ㄤ簬RSA鐨勭被 鐩稿綋瀹規槗
Ⅳ 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語言的,多謝。
//rsa.h
#include<stdio.h>
#defineMAX_NUM63001
#defineMAX_PRIME251
//!返回代碼
#defineOK100
#defineERROR_NOEACHPRIME101
#defineERROR_NOPUBLICKEY102
#defineERROR_GENERROR103
unsignedintMakePrivatedKeyd(unsignedintuiP,unsignedintuiQ);
unsignedintGetPrivateKeyd(unsignedintiWhich);
unsignedintMakePairkey(unsignedintuiP,unsignedintuiQ,unsignedintuiD);
unsignedintGetPairKey(unsignedint&d,unsignedint&e);
voidrsa_encrypt(intn,inte,char*mw,intiLength,int*&cw);
voidrsa_decrypt(intn,intd,int*&cw,intcLength,char*mw);
voidoutputkey();
//rsa.c
#include"rsa.h"
//!保存私鑰d集合
structpKeyset
{
unsignedintset[MAX_NUM];
unsignedintsize;
}pset;
//!保存公、私鑰對
structpPairkey
{
unsignedintd;
unsignedinte;
unsignedintn;
}pairkey;
//名稱:isPrime
//功能:判斷兩個數是否互質
//參數:m:數a;n:數b
//返回:m、n互質返回true;否則返回false
boolisPrime(unsignedintm,unsignedintn)
{
unsignedinti=0;
boolFlag=true;
if(m<2||n<2)
returnfalse;
unsignedinttem=(m>n)?n:m;
for(i=2;i<=tem&&Flag;i++)
{
boolmFlag=true;
boolnFlag=true;
if(m%i==0)
mFlag=false;
if(n%i==0)
nFlag=false;
if(!mFlag&&!nFlag)
Flag=false;
}
if(Flag)
returntrue;
else
returnfalse;
}
//名稱:MakePrivatedKeyd
//功能:由素數Q、Q生成私鑰d
//參數:uiP:素數P;uiQ:素數Q
//返回:私鑰d
unsignedintMakePrivatedKeyd(unsignedintuiP,unsignedintuiQ)
{
unsignedinti=0;
//!得到所有與z互質的數(私鑰d的集合)
unsignedintz=(uiP-1)*(uiQ-1);
pset.size=0;
for(i=0;i<z;i++)
{
if(isPrime(i,z))
{
pset.set[pset.size++]=i;
}
}
returnpset.size;
}
//名稱:MakePairKey
//功能:生成RSA公、私鑰對
//參數:uiP:素數P;uiQ:素數Q;uiD:私鑰d
//返回:錯誤代碼
unsignedintMakePairkey(unsignedintuiP,unsignedintuiQ,unsignedintuiD)
{
boolbFlag=true;
unsignedinti=0,e;
unsignedintz=(uiP-1)*(uiQ-1);
unsignedintd=pset.set[uiD];
//d=uiD;
if(!isPrime(z,d))
returnERROR_NOEACHPRIME;
for(i=2;i<z;i++)
{
if((i*d)%z==1)
{
e=i;
bFlag=false;
}
}
if(bFlag)
returnERROR_NOPUBLICKEY;
if((d*e)%z!=1)
ERROR_GENERROR;
pairkey.d=d;
pairkey.e=e;
pairkey.n=uiP*uiQ;
returnOK;
}
//名稱:GetPairKey
//功能:對外提供介面,獲得公、私鑰對
//參數:uiP:素數P;uiQ:素數Q;uiD:私鑰d
//返回:
unsignedintGetPairKey(unsignedint&d,unsignedint&e)
{
d=pairkey.d;
e=pairkey.e;
returnpairkey.n;
}
//名稱:GetPrivateKeyd
//功能:對外提供介面,由用戶選擇ID得以私鑰d
//參數:iWhich:用戶選擇私鑰d的ID
//返回:私鑰d值
unsignedintGetPrivateKeyd(unsignedintiWhich)
{
if(pset.size>=iWhich)
returnpset.set[iWhich];
else
return0;
}
//名稱:rsa_encrypt
//功能:RSA加密運算
//參數:n:公鑰n;e:公鑰e;mw:加密明文;iLength:明文長度;cw:密文輸出
//返回:無
voidrsa_encrypt(intn,inte,char*mw,intmLength,int*&cw)
{
inti=0,j=0;
__int64temInt=0;
for(i=0;i<mLength;i++)
{
temInt=mw[i];
if(e!=0)
{
for(j=1;j<e;j++)
{
temInt=(temInt*mw[i])%n;
}
}
else
{
temInt=1;
}
cw[i]=(int)temInt;
}
}
//名稱:rsa_decrypt
//功能:RSA解密運算
//參數:n:私鑰n;d:私鑰d;cw:密文;cLength:密文長度;mw:明文輸出
//返回:無
voidrsa_decrypt(intn,intd,int*&cw,intcLength,char*mw)
{
inti=0,j=-1;
__int64temInt=0;
for(i=0;i<cLength/4;++i)
{
mw[i]=0;
temInt=cw[i];
if(d!=0)
{
for(j=1;j<d;j++)
{
temInt=(__int64)(temInt*cw[i])%n;
}
}
else
{
temInt=1;
}
mw[i]=(char)temInt;
}
}
voidoutputkey()
{
printf("PublicKey(e,n):(%d,%d) ",pairkey.e,pairkey.n);
printf("PrivateKey(d,n):(%d,%d) ",pairkey.d,pairkey.n);
}
//main.c
//工程:RSA
//功能:RSA加、解密文件
//作者:jlcss|ExpNIS
#include<stdio.h>
#include<afxwin.h>
#include<math.h>
#include"rsa.h"
#defineDECRYPT_FILE"RSA加密密文.txt"
#defineENCRYPT_FILE"RSA解密明文.txt"
//!約束文件最大2M
#defineMAX_FILE1024*1024*2
//名稱:usage
//功能:幫助信息
//參數:應用程序名稱
//返回:提示信息
voidUsage(constchar*appname)
{
printf(" usage:rsa-k素數P素數Q ");
printf(" usage:rsa-e明文文件公鑰e公鑰n ");
printf(" usage:rsa-d密文文件私鑰d私鑰n ");
}
//名稱:IsNumber
//功能:判斷數字字元數組
//參數:strNumber:字元數組
//返回:數字字組數組返回true,否則返回false;
boolIsNumber(constchar*strNumber)
{
unsignedinti;
if(!strNumber)
returnfalse;
for(i=0;i<strlen(strNumber);i++)
{
if(strNumber[i]<'0'||strNumber[i]>'9')
returnfalse;
}
returntrue;
}
//名稱:IsPrimeNumber
//功能:判斷素數
//參數:num:輸入整數
//返回:素數返回true,否則返回false;
boolIsPrimeNumber(unsignedintnum)
{
unsignedinti;
if(num<=1)
returnfalse;
unsignedintsqr=(unsignedint)sqrt((double)num);
for(i=2;i<=sqr;i++)
{
if(num%i==0)
returnfalse;
}
returntrue;
}
//名稱:FileIn
//功能:讀取磁碟文件到內存
//參數:strFile:文件名稱;inBuff:指向文件內容緩沖區
//返回:實際讀取內容大小(位元組)
intFileIn(constchar*strFile,unsignedchar*&inBuff)
{
intiFileLen=0,iBuffLen=0;
//!打開密文文件
CFilefile(strFile,CFile::modeRead);
iFileLen=(int)file.GetLength();
if(iFileLen>MAX_FILE)
{
printf("文件長度不能大於%dM,! ",MAX_FILE/(1024*1024));
gotoout;
}
iBuffLen=iFileLen;
inBuff=newunsignedchar[iBuffLen];
if(!inBuff)
gotoout;
ZeroMemory(inBuff,iBuffLen);
file.Read(inBuff,iFileLen);
file.Close();
out:
returniBuffLen;
}
//名稱:FileOut
//功能:加/解密結果輸出到當前目錄磁碟文件中
//參數:strOut指向輸出字元緩沖區,輸出大小len,strFile為輸出文件
//返回:無
voidFileOut(constvoid*strOut,intlen,constchar*strFile)
{
//!輸出到文件
CFileoutfile(strFile,CFile::modeCreate|CFile::modeWrite);
outfile.Write(strOut,len);
outfile.Close();
}
//名稱:CheckParse
//功能:校驗應用程序入口參數
//參數:argc等於main主函數argc參數,argv指向main主函數argv參數
//返回:若參數合法返回true,否則返回false
//備註:簡單的入口參數校驗
boolCheckParse(intargc,char**argv)
{
boolbRes=false;
if(argc!=4&&argc!=5)
gotoout;
if(argc==4&&argv[1][1]=='k')
{
//!生成公、私鑰對
if(!IsNumber(argv[2])||
!IsNumber(argv[3])||
atoi(argv[2])>MAX_PRIME||
atoi(argv[3])>MAX_PRIME)
gotoout;
}
elseif((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)
gotoout;
}
else
Usage(*argv);
bRes=true;
out:
returnbRes;
}
//名稱:kOption1
//功能:程序k選項操作:由素數P、Q生成私鑰d集合
//參數:uiP:程序入口參數P;uiQ:程序入口參數Q
//返回:執行正確返回生成私鑰數目,否則返回0
unsignedintkOption1(unsignedintuiP,unsignedintuiQ)
{
unsignedintuiRes=0;
if(!IsPrimeNumber(uiP))
{
printf("P輸入錯誤,P必須為(0,%d]素數",MAX_PRIME);
returnuiRes;
}
if(!IsPrimeNumber(uiQ))
{
printf("Q輸入錯誤,Q必須為(0,%d]素數",MAX_PRIME);
returnuiRes;
}
if(uiP==uiQ)
{
printf("素數P與素數Q相同,很容易根據公鑰n開平方得出素數P和Q,這種加密不安全,請更換素數! ");
returnuiRes;
}
printf("正在生成私鑰d集合...... ");
uiRes=MakePrivatedKeyd(uiP,uiQ);
returnuiRes;
}
//!程序主函數
intmain(intargc,char**argv)
{
unsignedintp,q,d,n,e;//twoprimep&q,publickey(n,e),privatekey(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();
}
elseif(argc==5)
{
charFileName[20];
strcpy(FileName,argv[2]);
intlen;
if(argv[1][1]=='e')
{
unsignedchar*inBuffer=(unsignedchar*)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);
}
elseif(argv[1][1]=='d')
{
char*Buffer=(char*)malloc(MAX_FILE);//輸入緩沖區
int*cw=(int*)malloc(MAX_FILE);
len=FileIn(FileName,(unsignedchar*&)cw);
d=atoi(argv[3]);
n=atoi(argv[4]);
rsa_decrypt(n,d,cw,len,Buffer);
FileOut(Buffer,len/4,ENCRYPT_FILE);
}
}
return0;
}
Ⅵ 如何用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;
}