Go 實(shí)現(xiàn)RSA加密解密

什么是RSA

RSA是1977年由羅納德·李維斯特(Ron Rivest)、阿迪·薩莫爾(Adi Shamir)和倫納德·阿德曼(Leonard Adleman)一起提出的甲雅。當(dāng)時他們?nèi)硕荚诼槭±砉W(xué)院工作。RSA就是他們?nèi)诵帐祥_頭字母拼在一起組成的。

RSA可以被用于公鑰密碼和數(shù)字簽名。

RSA加密解密

公鑰加密->私鑰解密 (接收者密鑰對)

公鑰與密鑰的產(chǎn)生

假設(shè)Alice想要通過一個不可靠的媒體接收Bob的一條私人訊息宏所。她可以用以下的方式來產(chǎn)生一個公鑰和一個私鑰

  1. 隨意選擇兩個大的質(zhì)數(shù)pqp不等于q叽掘,計(jì)算N=pq楣铁。
  2. 根據(jù)歐拉函數(shù),求得r = (p-1)(q-1)
  3. 選擇一個小于 r 的整數(shù)* e*更扁,求得 e 關(guān)于模 r 的模反元素盖腕,命名為d赫冬。(模反元素存在,當(dāng)且僅當(dāng)e與r互質(zhì))
  4. 將* p q *的記錄銷毀溃列。

(N,e)是公鑰劲厌,(N,d)是私鑰。Alice將她的公鑰(N,e)傳給Bob听隐,而將她的私鑰(N,d)藏起來补鼻。

加密消息

假設(shè)Bob想給Alice送一個消息m,他知道Alice產(chǎn)生的Ne雅任。他使用起先與Alice約好的格式將m轉(zhuǎn)換為一個小于N的整數(shù)n风范,比如他可以將每一個字轉(zhuǎn)換為這個字的Unicode碼,然后將這些數(shù)字連在一起組成一個數(shù)字沪么。假如他的信息非常長的話硼婿,他可以將這個信息分為幾段,然后將每一段轉(zhuǎn)換為n禽车。用下面這個公式他可以將n加密為c

ne ≡ c (mod N)

計(jì)算c并不復(fù)雜寇漫。Bob算出c后就可以將它傳遞給Alice。

解密消息

Alice得到Bob的消息c后就可以利用她的密鑰d來解碼殉摔。她可以用以下這個公式來將c轉(zhuǎn)換為n

cd ≡ n (mod N)

得到n后州胳,她可以將原來的信息m重新復(fù)原。

解碼的原理是:

cd ≡ n e·d(mod N)

以及ed ≡ 1 (mod p-1)和ed ≡ 1 (mod q-1)逸月。由費(fèi)馬小定理可證明(因?yàn)?em>p和q是質(zhì)數(shù))

n e·d ≡ n (mod p)   和  n e·d ≡ n (mod q)

這說明(因?yàn)?em>p和q不同的質(zhì)數(shù)栓撞,所以pq互質(zhì))

n e·d ≡ n (mod pq)

簽名消息

私鑰加密->公鑰解密過程 (發(fā)送者密鑰對)

作用

1、數(shù)據(jù)完整性2彻采、數(shù)據(jù)來源的安全性

RSA也可以用來為一個消息署名腐缤。假如甲想給乙傳遞一個署名的消息的話捌归,那么她可以為她的消息計(jì)算一個散列值(Message digest)肛响,然后用她的密鑰(private key)加密這個散列值并將這個“署名”加在消息的后面。這個消息只有用她的公鑰才能被解密惜索。乙獲得這個消息后可以用甲的公鑰解密這個散列值特笋,然后將這個數(shù)據(jù)與他自己為這個消息計(jì)算的散列值相比較。假如兩者相符的話巾兆,那么他就可以知道發(fā)信人持有甲的密鑰猎物,以及這個消息在傳播路徑上沒有被篡改過。
圖解:

image

方式一:使用RSA完成簽名驗(yàn)簽過程

代碼實(shí)現(xiàn) :

package main

import (
    "crypto"
    "crypto/md5"
    "crypto/rand"
    "crypto/rsa"
    "fmt"
)
//rsa加密解密 簽名驗(yàn)簽
func main() {
    //生成私鑰
    priv, e := rsa.GenerateKey(rand.Reader, 1024)
    if e != nil {
        fmt.Println(e)
    }

    //根據(jù)私鑰產(chǎn)生公鑰
    pub := &priv.PublicKey

    //明文
    plaintext := []byte("Hello world")

    //加密生成密文
    fmt.Printf("%q\n加密:\n", plaintext)
    ciphertext, e := rsa.EncryptOAEP(md5.New(), rand.Reader, pub, plaintext, nil)
    if e != nil {
        fmt.Println(e)
    }
    fmt.Printf("\t%x\n", ciphertext)

    //解密得到明文
    fmt.Printf("解密:\n")
    plaintext, e = rsa.DecryptOAEP(md5.New(), rand.Reader, priv, ciphertext, nil)
    if e != nil {
        fmt.Println(e)
    }
    fmt.Printf("\t%q\n", plaintext)

    //消息先進(jìn)行Hash處理
    h := md5.New()
    h.Write(plaintext)
    hashed := h.Sum(nil)
    fmt.Printf("%q MD5 Hashed:\n\t%x\n", plaintext, hashed)

    //簽名
    opts := &rsa.PSSOptions{SaltLength: rsa.PSSSaltLengthAuto, Hash: crypto.MD5}
    sig, e := rsa.SignPSS(rand.Reader, priv, crypto.MD5, hashed, opts)
    if e != nil {
        fmt.Println(e)
    }
    fmt.Printf("簽名:\n\t%x\n", sig)

    //認(rèn)證
    fmt.Printf("驗(yàn)證結(jié)果:")
    if e := rsa.VerifyPSS(pub, crypto.MD5, hashed, sig, opts); e != nil {
        fmt.Println("失敗:", e)
    } else {
        fmt.Println("成功.")
    }
}

簽名方式二:使用DSA完成簽名驗(yàn)簽過程

DSA是基于整數(shù)有限域離散對數(shù)難題的角塑,其安全性與RSA相比差不多蔫磨。DSA的一個重要特點(diǎn)是兩個素數(shù)公開,這樣圃伶,當(dāng)使用別人的p和q時堤如,即使不知道私鑰蒲列,你也能確認(rèn)它們是否是隨機(jī)產(chǎn)生的,還是作了手腳搀罢。RSA算法卻做不到蝗岖。

DSA是Schnorr算法與ElGammal方式的變體,只能被用于數(shù)字簽名榔至。

代碼實(shí)現(xiàn):

package main

import (
    "crypto/dsa"
    "crypto/rand"
    "fmt"
)

/*
DSA只能做簽名 驗(yàn)簽 無法做加密
*/
func main() {

    var params dsa.Parameters
    //生成參數(shù)
    dsa.GenerateParameters(&params,rand.Reader,dsa.L1024N160)
    //生成私鑰
    var priv dsa.PrivateKey
    priv.Parameters = params
    dsa.GenerateKey(&priv,rand.Reader)

    //根據(jù)私鑰生成公鑰
    pub := priv.PublicKey

    //利用私鑰簽名數(shù)據(jù)
    msg := []byte("hello world")
    r,s,_ :=dsa.Sign(rand.Reader,&priv,msg)

    //公鑰驗(yàn)簽
    b := dsa.Verify(&pub,msg,r,s)
    if b == true {
        fmt.Println("驗(yàn)證成功")
    }
}

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末抵赢,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子唧取,更是在濱河造成了極大的恐慌铅鲤,老刑警劉巖,帶你破解...
    沈念sama閱讀 219,270評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件枫弟,死亡現(xiàn)場離奇詭異彩匕,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)媒区,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,489評論 3 395
  • 文/潘曉璐 我一進(jìn)店門驼仪,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人袜漩,你說我怎么就攤上這事绪爸。” “怎么了宙攻?”我有些...
    開封第一講書人閱讀 165,630評論 0 356
  • 文/不壞的土叔 我叫張陵奠货,是天一觀的道長。 經(jīng)常有香客問我座掘,道長递惋,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,906評論 1 295
  • 正文 為了忘掉前任溢陪,我火速辦了婚禮萍虽,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘形真。我一直安慰自己杉编,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,928評論 6 392
  • 文/花漫 我一把揭開白布咆霜。 她就那樣靜靜地躺著邓馒,像睡著了一般。 火紅的嫁衣襯著肌膚如雪蛾坯。 梳的紋絲不亂的頭發(fā)上光酣,一...
    開封第一講書人閱讀 51,718評論 1 305
  • 那天,我揣著相機(jī)與錄音脉课,去河邊找鬼救军。 笑死改览,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的缤言。 我是一名探鬼主播宝当,決...
    沈念sama閱讀 40,442評論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼胆萧!你這毒婦竟也來了庆揩?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,345評論 0 276
  • 序言:老撾萬榮一對情侶失蹤跌穗,失蹤者是張志新(化名)和其女友劉穎订晌,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體蚌吸,經(jīng)...
    沈念sama閱讀 45,802評論 1 317
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡锈拨,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,984評論 3 337
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了羹唠。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片奕枢。...
    茶點(diǎn)故事閱讀 40,117評論 1 351
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖佩微,靈堂內(nèi)的尸體忽然破棺而出缝彬,到底是詐尸還是另有隱情,我是刑警寧澤哺眯,帶...
    沈念sama閱讀 35,810評論 5 346
  • 正文 年R本政府宣布谷浅,位于F島的核電站,受9級特大地震影響奶卓,放射性物質(zhì)發(fā)生泄漏一疯。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,462評論 3 331
  • 文/蒙蒙 一夺姑、第九天 我趴在偏房一處隱蔽的房頂上張望墩邀。 院中可真熱鬧,春花似錦瑟幕、人聲如沸磕蒲。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,011評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至兔院,卻和暖如春殖卑,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背坊萝。 一陣腳步聲響...
    開封第一講書人閱讀 33,139評論 1 272
  • 我被黑心中介騙來泰國打工孵稽, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留许起,地道東北人。 一個月前我還...
    沈念sama閱讀 48,377評論 3 373
  • 正文 我出身青樓菩鲜,卻偏偏與公主長得像园细,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子接校,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,060評論 2 355