1. 程式人生 > >RSA加密演算法及程式碼示例

RSA加密演算法及程式碼示例

以下程式碼使用PowerBuilder作為示例

1、資料加密概述
早在幾千年前人類就已經有了通訊保密的思想和方法。但直到1949年,資訊理論創始人夏農發表著名文章,論證了一般經典加密方法得到的密文幾乎都是可破譯的。密碼學才得以進入了一個新的發展時期。70年代後期,美國的資料加密標準DES和公開金鑰密碼體制的出現成為近代密碼學發展史上的兩個重要里程碑。
公開金鑰密碼體制的概念是由Difie與Hellman於1976年提出。所謂公開金鑰密碼體制就是加密金鑰與解密金鑰不同,是一種由已知加密金鑰推匯出解密金鑰在計算上是不可行的密碼體制。其中,基於數論中大數分解問題的RSA體制曾被ISO/TC97的資料加密技術委員會SC20推薦為公開金鑰資料加密標準。

2、RSA體制的基本原理
該體制是根據尋求兩個大素數比較簡單,而將它們的乘積分解開則極其困難這一原理來設計的。在已提出的公開金鑰演算法中它是最容易理解和實現的。RSA在世界上許多地方已成事實上的標準。ISO幾乎(但沒有明確)已指定RSA用作數字簽名標準。該演算法已經經受住了多年深入的密碼分析,雖然密碼分析者既不能證明也不能否定RSA的安全性,但這恰恰說明了該演算法有一定的可信度。它的安全性是與大數分解密切相關的。我想通過下表你將會對它的安全性有一個較好的認識,它給出了在計算機每一微妙做一次操作的假定下分解不同大小的N所需要的時間。

  N的十進位數  50    75    100   200 

  時間      3.9小時  104天  74年  3.8X1015年 

RSA加密演算法具體如下:
(1)選取兩個大素數,p和q。為了獲得最大程式的安全性,兩個素數的長度一樣。並計算乘積N(N=pq)。
(2) 隨後計算出N的尤拉函式ф(N)=(p-1)(q-1),ф(N)定義為不超過N並與N互素的數的個數。
(3)從[0,ф(N)- 1]中隨機選取加密金鑰e,使得e和ф(N)互為素數。
(4)計算出滿足公式ed=1 modф(N)的d,d為解密金鑰。
(5)若用整數X表示明文,整數Y表示密文(X,Y均小於N),則加解密運算為:
加密:Y = Xe mod N
解密:X = Yd mod N
注意,其中的d和N也互素。e和N是公開金鑰,d是祕密金鑰。兩個素數p和q應捨棄,但千萬不要洩密哦。

3、相關數學背景知識
(1)素數:素數是一個比1大,其因子只有1和它本身,沒有其它數可以整除它的數。素數是無限的。例如,2,3,5,7……等。
(2)兩個數互為素數:指的是它們除了1之外沒有共同的因子。也可以說這兩個數的最大公因子是1。例如,4和9,13和27等。
(3)模變換:兩個數相模,如A模N運算,它給出了A的餘數,餘數是從0到N-1的某個整數,這種運算稱為模運算。
4、演算法的具體實現
從RSA的基本原理我們得知,對明文進行加密選擇一個合適的e很重要,如果你選擇合適的話,RSA的加密速度將快得多,並且也不會因為使用者機器的限制而要做更多的變換(指在計算中為了避免資料的溢位所進行的轉換,畢竟我們用的是PC機再說也用不著很高的安全性)。最常用的三個e值是3,17,65537。在這裡我們取的e等於3,當然到底選取哪個e值並沒有規定,這裡只是為了演示方便罷了。
根據演算法定義,
(1)為了方便起見我們選取素數p = 3和q = 11,則N = pq = 3 * 11 = 33。
(2)ф(N)=(p-1)(q-1)= 2 * 10 = 20。
(3)從[0,ф(N) - 1]中,即,[0, 19]之間任意選取加密金鑰e = 3,且e和ф(N)互素。
(4)如何從公式ed=1 modф(N)求出解密金鑰d?
由模的定理我們可以將公式ed=1 modф(N)轉換成形式ed= k * ф(N)+ 1,即3d = k * 20 + 1,將0,1,2,3…依次代入k,求出d。取k = 1,得d = 7。
讀者可以通過程式設計實現隨機選取p和q來求出相應的N,e,d。
(5)進行加解密。
對明文進行加密
根據定義,我們首先要根據N的值對明文進行分組,每個分組的值應小於N。如果要加密固定的訊息分組,那麼可以在它的左邊填充一些0(零)並確保該值比N小。例如,我們要對資料X=172035594進行加密(在我的計算機上C盤的序列號是0A41-0E0A,轉換成十進位制就是172035594),我們首先要將它分成小於N(N=33)的若干小組。可以分成,X1=17,X2=20,X3=3,X4=5,X5=5,X6=9,X7=4。對第一分組X1運用加密公式得到加密密文Y1=X1e mod N = 173 mod 33 = 29,依次將其餘分組進行加密得到,Y2=14,Y3=27,Y4=26,Y5=26,Y6=3,Y7=31。即密文Y= 2914272626331。我們可以將密文儲存在檔案或登錄檔中,每當應用程式啟動時先讀取密文,並將其解密,再將解密後的結果與硬碟序列號進行比較,以此來判斷軟體是否合法。在實際運用中我們可以隨時通過程式修改密文,比如,將密文去掉一位或將密文顛倒等,就可以實現諸如測試版軟體的使用限制問題,
對密文進行解密
對密文進行解密同樣要首先對密文進行分組,使每個分組都小於N。將密文Y=2914272626331分組成:
Y1=29,Y2=14,Y3=27,Y4=26,Y5=26,Y6=3,Y7=31
這時我們一定要注意,不要急於將將各分組代入解密公式X=Yd mod N,如果這樣做了我們所得到的明文將是X=1202811913,並不是加密時的明文!是不是加密演算法有錯?絕對不是。回顧加解密的公式,我們不難發現它們做的都是先將一個數進行n次方運算然後在做模運算。問題就出在“n次方運算”上,千萬不要忽略PowerBuilder中數值的取值範圍,在其它的程式語言中也是如此。在本例中我給明文和密文用的都是unsigned long型別,它的32位所允許最大值是4294967295,的確很大,但我們不能保證一個數在進行了7次方後不超過該最大值。其實,這種情況在對明文加密時也是會發生的,只是33的3次方是35937,遠小於最大值,我們將其忽略罷了。
好在問題並不像我們想象的那麼複雜。由模的運算規律得知,模運算像普通的運算一樣,它是可交換的、可結合的、可分配的。而且,簡化運算每一箇中間結果的模n運算,其作用與先進行全部運算,然後再簡化模n運算是一樣的。比如,
(A * B) mod N = ((A mod N) * (B mod N)) mod N。
因此,
X = Y7 mod N
= (Y3 * Y4)mod N
= ((Y3 mod N)*(Y4 mod N))mod N
當然,我們也可以將Y7分解成更多項的乘積。將分組後的密文Y1至Y7依次代入上式得出密文為X = 17 20 3 5 5 9 4。即為正確明文,解密成功。
在實際的運用中考慮到PB沒有現成的乘方運算函式,為了便於讀者理解原程式是如何實現RSA加密演算法的本文所採用的方法是通過FOR…NEXT語句迴圈來實現乘方運算,讀者可以將其做成一個函式,在使用的時候呼叫。RSA加解密演算法的完整程式程式碼如下:

// 以下引數由RSA加密演算法得來
integer li_e, li_d, li_n
li_e = 3 // 設定指數e,加密金鑰
li_d = 7 // 設定指數d,解密金鑰
li_n = 33 // 設定N:兩個素數得乘積

string ls_str
ls_str = Trim(sle_1.text) // 將明文轉換成字串,以便隨後進行分組
ulong lul_temp
lul_temp = 0

ulong lul_x, lul_y // lul_x: 加密明文; lul_y: 加密密文
int I
do until ls_str = “”
lul_temp = Integer(left(ls_str, 2))
if lul_temp >= li_n then // 將明文分組,且每組均小於N(N=33)
lul_temp = Integer(left(ls_str, 1))
ls_str = right(ls_str, len(ls_str)-1)
else
ls_str = right(ls_str, len(ls_str)-2)
end if
lul_y = 1
for I = 1 to li_e // 進行乘方運算
lul_y = lul_y * lul_temp
next
lul_y = mod( lul_y, 33) // 根據加密公式計算密文
sle_2.text = trim(sle_2.text) + string(lul_y) // sle_2.tex中存放的是加密後的密文
loop


ls_str = Trim(sle_2.text) // 與加密同理,將密文轉換成字串,以便隨後進行分組
ulong lul_x0, lul_x1
do until ls_str = “”
lul_temp = Integer(left(ls_str, 2))
if lul_temp >= li_n then // 將密文分組,且每組均小於N(N=33)
lul_temp = Integer(left(ls_str, 1))
ls_str = right(ls_str, len(ls_str)-1)
else
ls_str = right(ls_str, len(ls_str)-2)
end if

// 由於考慮到乘方運算得結果可能會超出數值所允許得最大取值,
// 因此對解密公式進行適當轉換,lul_x = lul_x0 * lul_x1
lul_x0 = 1
lul_x1 = 1

// 假如解密金鑰是7,則先進行數的4次方運算取模,在進行數的3次方運算取模
for I = 1 to 4
lul_x0 = lul_x0 * lul_temp
next
lul_x0 = mod( lul_x0, 33)

for I = 1 to li_d – 4
lul_x1 = lul_x1 * lul_temp
next
lul_x1 = mod( lul_x1, 33)

lul_x = mod(lul_x0 * lul_x1, 33) // 根據解密公式計算明文
sle_3.text = trim(sle_3.text) + string(lul_x) // sle_3.tex中存放的是解密後的明文
loop

相關推薦

RSA加密演算法程式碼示例

以下程式碼使用PowerBuilder作為示例 1、資料加密概述 早在幾千年前人類就已經有了通訊保密的思想和方法。但直到1949年,資訊理論創始人夏農發表著名文章,論證了一般經典加密方法得到的密文幾乎都是可破譯的。密碼學才得以進入了一個新的發展時期。70年代後期,美國的

RSA加密演算法Java程式碼示例

看到別人整理好的RSA程式碼,作為收集如下: 建立RSA公私鑰 package rsa;    import java.io.BufferedReader;   import java.io.BufferedWriter;   import java.io.FileRead

openssl AES 加密演算法程式碼例項

一、AES演算法簡介 1、AES演算法介紹         密碼學中的高階加密標準(Advanced Encryption Standard,AES),又稱 Rijndael加密法,是美國聯邦政府採用的一種區塊加密標準。這個標準用來替代原先的DES,已經被多方分析且廣

RSA加密演算法特定條件下的破解

在對稱加密演算法中,資訊的傳送方和接收方用同樣的金鑰對資訊進行加密和解密,而如何安全傳遞key本身成為了一個十分嚴重的問題,因此產生了公開金鑰密碼體制。 公開金鑰密碼體制使用不同的金鑰來進行加密和解密,加密金鑰公開(公鑰),而解密金鑰私有(私鑰),加密演算法和解密演算法都是

淺談常見的七種加密演算法實現(附程式碼

1. 前言 數字簽名、資訊加密 是前後端開發都經常需要使用到的技術,應用場景包括了使用者登入、交易、資訊通訊、oauth 等等,不同的應用場景也會需要使用到不同的簽名加密演算法,或者需要搭配不一樣的 簽名加密演算法來達到業務目標。這裡簡單的給大家介紹幾種常見的簽

JAVA利用RSA加密演算法的長度限制問題解決完整程式碼

package com.additional; import java.io.ByteArrayOutputStream;   import java.security.Key;   import java.security.KeyFactory;   import jav

樸素貝葉斯演算法學習程式碼示例

       最近工作中涉及到文字分類問題,於是就簡單的看了一下樸素貝葉斯演算法(Naive Bayes),以前對該演算法僅僅停留在概念上的瞭解,這次系統的查閱資料學習了一下。樸素貝葉斯演算法以貝葉斯

C#自定義RSA加密解密RSA簽名和驗證類實例

狀態 share normal evel thumb weight encrypt security clas 本文實例講述了C#自定義RSA加密解密及RSA簽名和驗證類。分享給大家供大家參考。具體分析如下: 這個C#類自定義RSA加密解密及RSA簽名和驗證,包含了RSA

RSA加密解密數字簽名Java實現

cto 包括 sign object misc 數據 factory 了解 對稱密鑰 RSA公鑰加密算法是1977年由羅納德·李維斯特(Ron Rivest)、阿迪·薩莫爾(Adi Shamir)和倫納德·阿德曼(Leonard Adleman)一起提出的。當時他們三人都在

RSA加密演算法簡單分析

         預備知識       1)RSA是第一個比較完善的公開金鑰演算法,它既能用於加密,也能用於數字簽名。RSA以它的三個發明者Ron Rivest,

IdentityServer4之JWT簽名(RSA加密證書)驗籤

一、前言  在IdentityServer4中有兩種令牌,一個是JWT和Reference Token,在IDS4中預設用的是JWT,那麼這兩者有什麼區別呢?   二、JWT與Reference Token的區別  1、JWT(不可撤回)  

RSA加密演算法生成公鑰和私鑰

Java RSA加密演算法生成公鑰和私鑰 import java.security.Key; import java.security.KeyPair; import java.security.KeyPairGenerator; import java.security.interf

RSA加密演算法驗證(C#實現)

RSA演算法簡單原理介紹(節選於網路) 假設Alice想要通過一個不可靠的媒體接收Bob的一條私人訊息。她可以用以下的方式來產生一個公鑰和一個私鑰: 隨意選擇兩個大的質數p和q,p不等於q,計算N=pq。 根據尤拉函式,求得r = (p-1)(q-1) 選擇一個小於 r

機器學習-*-MeanShift聚類演算法程式碼實現

MeanShift 該演算法也叫做均值漂移,在目標追蹤中應用廣泛。本身其實是一種基於密度的聚類演算法。 主要思路是:計算某一點A與其周圍半徑R內的向量距離的平均值M,計算出該點下一步漂移(移動)的方向(A=M+A)。當該點不再移動時,其與周圍點形成一個類簇,計算這個類簇與歷史類簇的距

Python實現RSA加密演算法

基本思路在這裡說一下: 設p、q為質數 n = p*q fn = (p-1)*(q-1) 要滿足: 1 < e < fn , 且 e 與 fn 互質 滿足: e*d%fn = 1 (d>1) e 為公鑰 , d 為私鑰 把e 和 n 發給 客戶端 m 為明文 c =

springcloud系列21——Zuul簡介程式碼示例

Zuul簡介 路由是微服務架構的組成部分。 例如,/可以對映到您的Web應用程式,/ api/users對映到使用者服務,/api/shop對映到商店服務。 Zuul是Netflix基於JVM的路由器和伺服器端負載均衡器。 Netflix使用Zuul進行以下操

快速理解RSA加密演算法

RSA公開金鑰密碼體制 所謂的公開金鑰密碼體制就是使用不同的加密金鑰與解密金鑰,是一種“由已知加密金鑰推匯出解密金鑰在計算上是不可行的”密碼體制。 在公開金鑰密碼體制中,加密金鑰(即公開金鑰)PK是公開資訊,而解密金鑰(即祕密金鑰)SK是需要保密的。加密演算法E和解密演算法D也都是公開的。雖然解密金鑰SK是由

從檔案加密解密到RSA加密演算法

1.檔案的加密解密        其實檔案的加密解密我們可以理解成在複製檔案時對檔案中的每一個位元組做一些操作,比如最簡單的就是加上一個常數或一個隨機數,還有取模等,只要把它變成不是原本的模樣就OK了。       以下給出生成隨機數的方式加密:MyKey是一個生成128

機器學習(一)邏輯迴歸與softmax迴歸程式碼示例

本文適合已經對機器學習、人工智慧有過一定了解,但是還沒有自己寫過程式碼,或者一直在使用現有框架的同學。不用框架自己寫一次程式碼的過程還是很有必要的,能讓你真正地理解原理與機器學習中各個步驟的實現過程,而不是停留在“好像懂了”、只會調庫的階段。 目錄

【C++】如何進行簡單的檔案輸入、輸出?(基本操作程式碼示例)(程式設計習慣)

使用cin進行輸入時,程式將輸入 視為一系列的位元組,每個位元組都被解釋為字元編碼,輸入一開始都是字元資料。 輸出檔案開啟 //第一種 ofstream outFile; outFile.open("my.txt"); //第二種 ofstream fout; char filename[5