0
  • 聊天消息
  • 系統(tǒng)消息
  • 評(píng)論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫(xiě)文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

Go語(yǔ)言做對(duì)稱加密怎么做

開(kāi)關(guān)電源芯片 ? 來(lái)源:CSDN博客 ? 作者:尹成學(xué)院 ? 2021-08-23 09:44 ? 次閱讀

【導(dǎo)讀】什么是對(duì)稱加密?Go 語(yǔ)言做對(duì)稱加密怎么做?本文作者從加密原理到代碼實(shí)現(xiàn)帶你上車。

對(duì)稱加密中,加密和解密使用相同的密鑰,因此必須向解密者配送密鑰,即密鑰配送問(wèn)題。而非對(duì)稱加密中,由于加密和解密分別使用公鑰和私鑰,而公鑰是公開(kāi)的,因此可以規(guī)避密鑰配送問(wèn)題。非對(duì)稱加密算法,也稱公鑰加密算法。

1977 年,Ron Rivest、Adi Shamir、Leonard Adleman 三人在美國(guó)公布了一種公鑰加密算法,即 RSA 公鑰加密算法。RSA 是目前最有影響力和最常用的公鑰加密算法,可以說(shuō)是公鑰加密算法的事實(shí)標(biāo)準(zhǔn)。

一、RSA 加密原理

使用 M 和 C 分別表示明文和密文,則 RSA 加密、解密過(guò)程如下:

img

其中 e、n 的組合 (e, n) 即為公鑰,d、n 的組合 (d, n) 即為私鑰。當(dāng)然 e、d、n 并非任意取值,需要符合一定條件,如下即為 e、d、n 的求解過(guò)程。

生成密鑰對(duì)

e、d、n 的求解過(guò)程,也即生成密鑰對(duì)的過(guò)程。涉及如下步驟:1、取兩個(gè)大質(zhì)數(shù)(也稱素?cái)?shù))p、q,n = pq。2、取正整數(shù) e、d,使得 ed mod (p-1)(q-1) = 1,也即:ed ≡ 1 mod (p-1)(q-1)。e 和 d 是模 (p-1)(q-1) 的乘法逆元,僅當(dāng) e 與 (p-1)(q-1) 互質(zhì)時(shí),存在 d。舉例驗(yàn)證:1、取 p、q 分別為 13、17,n = pq = 221。2、而 (p-1)(q-1) = 12x16 = 192,取 e、d 分別為 13、133,有 13x133 mod 192 = 1取明文 M = 60,公鑰加密、私鑰解密,

RSA 加密原理證明過(guò)程

手動(dòng)求解密鑰對(duì)中的 d

ed mod (p-1)(q-1) = 1,已知 e 和 (p-1)(q-1) 求 d,即求 e 對(duì)模 (p-1)(q-1) 的乘法逆元。如上面例子中,p、q 為 13、17,(p-1)(q-1)=192,取 e=13,求 13d mod 192 = 1 中的 d。13d ≡ 1 (mod 192),在右側(cè)添加 192 的倍數(shù),使計(jì)算結(jié)果可以被 13 整除。13d ≡ 1 + 192x9 ≡ 13x133 (mod 192),因此 d = 133其他計(jì)算方法有:費(fèi)馬小定律、擴(kuò)展歐幾里得算法、歐拉定理。

RSA 安全性

由于公鑰公開(kāi),即 e、n 公開(kāi)。因此破解 RSA 私鑰,即為已知 e、n 情況下求 d。因 ed mod (p-1)(q-1) = 1,且 n=pq,因此該問(wèn)題演變?yōu)椋簩?duì) n 質(zhì)因數(shù)分解求 p、q。目前已被證明,已知 e、n 求 d 和對(duì) n 質(zhì)因數(shù)分解求 p、q 兩者是等價(jià)的。實(shí)際中 n 長(zhǎng)度為 2048 位以上,而當(dāng) n》200 位時(shí)分解 n 是非常困難的,因此 RSA 算法目前仍被認(rèn)為是安全實(shí)用的。

RSA 計(jì)時(shí)***和防范

RSA 解密的本質(zhì)是模冪運(yùn)算

img

其中 C 為密文,(d,n) 為私鑰,均為超過(guò) 1024 位的大數(shù)運(yùn)算,直接計(jì)算并不可行,因此最經(jīng)典的算法為蒙哥馬利算法。而這種計(jì)算是比較是耗時(shí)的,因此者可以觀察不同的輸入對(duì)應(yīng)的解密時(shí)間,通過(guò)分析推斷私鑰,稱為計(jì)時(shí)。而防范 RSA 計(jì)時(shí)的辦法,即在解密時(shí)加入隨機(jī)因素,使得***者無(wú)法準(zhǔn)確獲取解密時(shí)間。

二、Go RSA 加密解密

1、rsa 加解密,必然會(huì)去查 crypto/ras 這個(gè)包

Package rsa implements RSA encryption as specified in PKCS#1.

這是該包的說(shuō)明:實(shí)現(xiàn) RSA 加密技術(shù),基于 PKCS#1 規(guī)范。

對(duì)于什么是 PKCS#1,可以查閱相關(guān)資料。PKCS(公鑰密碼標(biāo)準(zhǔn)),而#1 就是 RSA 的標(biāo)準(zhǔn)??梢圆榭矗篜KCS 系列簡(jiǎn)介

從該包中函數(shù)的名稱,可以看到有兩對(duì)加解密的函數(shù)。

EncryptOAEP 和 DecryptOAEPEncryptPKCS1v15 和 DecryptPKCS1v15

這稱作加密方案,詳細(xì)可以查看,PKCS #1 v2.1 RSA 算法標(biāo)準(zhǔn)

可見(jiàn),當(dāng)與其他語(yǔ)言交互時(shí),需要確定好使用哪種方案。

PublicKey 和 PrivateKey 兩個(gè)類型分別代表公鑰和私鑰,關(guān)于這兩個(gè)類型中成員該怎么設(shè)置,這涉及到 RSA 加密算法,本文中,這兩個(gè)類型的實(shí)例通過(guò)解析文章開(kāi)頭生成的密鑰得到。

2、解析密鑰得到 PublicKey 和 PrivateKey 的實(shí)例

這個(gè)過(guò)程,我也是花了好些時(shí)間(主要對(duì)各種加密的各種東東不熟):怎么將 openssl 生成的密鑰文件解析到公鑰和私鑰實(shí)例呢?

在 encoding/pem 包中,看到了—–BEGIN Type—–這樣的字樣,這正好和 openssl 生成的密鑰形式差不多,那就試試。

在該包中,一個(gè) block 代表的是 PEM 編碼的結(jié)構(gòu),關(guān)于 PEM,請(qǐng)查閱相關(guān)資料。我們要解析密鑰,當(dāng)然用 Decode 方法:

func Decode(data []byte) (p *Block, rest []byte)

這樣便得到了一個(gè) Block 的實(shí)例(指針)。

解析來(lái)看 crypto/x509。為什么是 x509 呢?這又涉及到一堆概念。先不管這些,我也是看 encoding 和 crypto 這兩個(gè)包的子包摸索出來(lái)的。在 x509 包中,有一個(gè)函數(shù):

func ParsePKIXPublicKey(derBytes []byte) (pub interface{}, err error)

從該函數(shù)的說(shuō)明:ParsePKIXPublicKey parses a DER encoded public key. These values are typically found in PEM blocks with “BEGIN PUBLIC KEY”??梢?jiàn)這就是解析 PublicKey 的。另外,這里說(shuō)到了 PEM,可以上面的 encoding/pem 對(duì)了。(PKIX 是啥東東,查看這里 )

而解析私鑰的,有好幾個(gè)方法,從上面的介紹,我們知道,RSA 是 PKCS#1,剛好有一個(gè)方法:

func ParsePKCS1PrivateKey(der []byte) (key *rsa.PrivateKey, err error)

返回的就是 rsa.PrivateKey。

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

package main

import (

“crypto/rsa”

“crypto/rand”

“crypto/x509”

“encoding/pem”

“os”

“fmt”

func RSAGenKey(bits int) error {

/*

生成私鑰

*/

//1、使用 RSA 中的 GenerateKey 方法生成私鑰

privateKey, err := rsa.GenerateKey(rand.Reader, bits)

if err != nil {

return err

}

//2、通過(guò) X509 標(biāo)準(zhǔn)將得到的 RAS 私鑰序列化為:ASN.1 的 DER 編碼字符串

privateStream := x509.MarshalPKCS1PrivateKey(privateKey)

//3、將私鑰字符串設(shè)置到 pem 格式塊中

block1 := pem.Block{

Type: “private key”,

Bytes: privateStream,

}

//4、通過(guò) pem 將設(shè)置的數(shù)據(jù)進(jìn)行編碼,并寫(xiě)入磁盤(pán)文件

fPrivate, err := os.Create(“privateKey.pem”)

if err != nil {

return err

}

defer fPrivate.Close()

err = pem.Encode(fPrivate, &block1)

if err != nil {

return err

}

/*

生成公鑰

*/

publicKey:=privateKey.PublicKey

publicStream,err:=x509.MarshalPKIXPublicKey(&publicKey)

//publicStream:=x509.MarshalPKCS1PublicKey(&publicKey)

block2:=pem.Block{

Type:“public key”,

Bytes:publicStream,

}

fPublic,err:=os.Create(“publicKey.pem”)

if err!=nil {

return err

}

defer fPublic.Close()

pem.Encode(fPublic,&block2)

return nil

}

//對(duì)數(shù)據(jù)進(jìn)行加密操作

func EncyptogRSA(src []byte,path string) (res []byte,err error) {

//1. 獲取秘鑰(從本地磁盤(pán)讀?。?/p>

f,err:=os.Open(path)

if err!=nil {

return

}

defer f.Close()

fileInfo,_:=f.Stat()

b:=make([]byte,fileInfo.Size())

f.Read(b)

// 2、將得到的字符串解碼

block,_:=pem.Decode(b)

// 使用 X509 將解碼之后的數(shù)據(jù) 解析出來(lái)

//x509.MarshalPKCS1PublicKey(block): 解析之后無(wú)法用,所以采用以下方法:ParsePKIXPublicKey

keyInit,err:=x509.ParsePKIXPublicKey(block.Bytes) //對(duì)應(yīng)于生成秘鑰的 x509.MarshalPKIXPublicKey(&publicKey)

//keyInit1,err:=x509.ParsePKCS1PublicKey(block.Bytes)

if err!=nil {

return

}

//4. 使用公鑰加密數(shù)據(jù)

pubKey:=keyInit.(*rsa.PublicKey)

res,err=rsa.EncryptPKCS1v15(rand.Reader,pubKey,src)

return

}

//對(duì)數(shù)據(jù)進(jìn)行解密操作

func DecrptogRSA(src []byte,path string)(res []byte,err error) {

//1. 獲取秘鑰(從本地磁盤(pán)讀?。?/p>

f,err:=os.Open(path)

if err!=nil {

return

}

defer f.Close()

fileInfo,_:=f.Stat()

b:=make([]byte,fileInfo.Size())

f.Read(b)

block,_:=pem.Decode(b)//解碼

privateKey,err:=x509.ParsePKCS1PrivateKey(block.Bytes)//還原數(shù)據(jù)

res,err=rsa.DecryptPKCS1v15(rand.Reader,privateKey,src)

return

}

func main() {

//rsa.GenerateKey()

err:=RSAGenKey(4096)

if err!=nil {

fmt.Println(err)

return

}

fmt.Println(“秘鑰生成成功!”)

str:=“山重水復(fù)疑無(wú)路,柳暗花明又一村!”

fmt.Println(“加密之前的數(shù)據(jù)為:”,string(str))

data,err:=EncyptogRSA([]byte(str),“publicKey.pem”)

data,err=DecrptogRSA(data,“privateKey.pem”)

fmt.Println(“加密之后的數(shù)據(jù)為:”,string(data))

}

責(zé)任編輯:haq

聲明:本文內(nèi)容及配圖由入駐作者撰寫(xiě)或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場(chǎng)。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問(wèn)題,請(qǐng)聯(lián)系本站處理。 舉報(bào)投訴
  • 代碼
    +關(guān)注

    關(guān)注

    30

    文章

    4694

    瀏覽量

    68075
  • RSA
    RSA
    +關(guān)注

    關(guān)注

    0

    文章

    59

    瀏覽量

    18837

原文標(biāo)題:GO 語(yǔ)言 RSA 加密解密

文章出處:【微信號(hào):gh_3980db2283cd,微信公眾號(hào):開(kāi)關(guān)電源芯片】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。

收藏 人收藏

    評(píng)論

    相關(guān)推薦

    三十分鐘入門(mén)基礎(chǔ)Go Java小子版

    前言 Go語(yǔ)言定義 Go(又稱 Golang)是 Google 的 Robert Griesemer,Rob Pike 及 Ken Thompson 開(kāi)發(fā)的一種靜態(tài)、強(qiáng)類型、編譯型語(yǔ)言
    的頭像 發(fā)表于 08-12 14:32 ?633次閱讀
    三十分鐘入門(mén)基礎(chǔ)<b class='flag-5'>Go</b> Java小子版

    nlp自然語(yǔ)言處理模型怎么做

    自然語(yǔ)言處理(Natural Language Processing,簡(jiǎn)稱NLP)是人工智能領(lǐng)域的一個(gè)重要分支,它涉及到計(jì)算機(jī)對(duì)人類語(yǔ)言的理解和生成。隨著深度學(xué)習(xí)技術(shù)的發(fā)展,NLP領(lǐng)域取得了顯著
    的頭像 發(fā)表于 07-05 09:59 ?431次閱讀

    c語(yǔ)言怎么做可視化界面

    C語(yǔ)言是一種通用的編程語(yǔ)言,廣泛應(yīng)用于系統(tǒng)編程、嵌入式開(kāi)發(fā)等領(lǐng)域。雖然C語(yǔ)言本身并不支持直接創(chuàng)建可視化界面,但通過(guò)結(jié)合一些圖形庫(kù)和工具,我們可以為C語(yǔ)言程序開(kāi)發(fā)出直觀、易用的可視化界面
    的頭像 發(fā)表于 06-06 10:46 ?1712次閱讀

    變壓器CE認(rèn)證怎么做

    變壓器CE認(rèn)證需要進(jìn)行的是歐盟EMC指令,由于需要了解是否使用與低電壓指令需要對(duì)變壓器的電壓進(jìn)行了解,一般而言是不適用于低電壓指令。變壓器CE認(rèn)證怎么做?需要對(duì)變壓器CE認(rèn)證的產(chǎn)品進(jìn)行評(píng)估,進(jìn)行指令
    的頭像 發(fā)表于 05-24 14:45 ?409次閱讀
    變壓器CE認(rèn)證<b class='flag-5'>怎么做</b>

    G473使用TIM1非對(duì)稱模式移相,用TIM8Combined PWM模式做對(duì)角的移相與門(mén)輸出,為什么時(shí)序不對(duì)?

    G473使用TIM1非對(duì)稱模式移相,用TIM8Combined PWM模式做對(duì)角的移相與門(mén)輸出,為啥占空比對(duì)了時(shí)序不對(duì)?
    發(fā)表于 03-14 07:49

    對(duì)稱加密算法工作模式詳解

    對(duì)稱密碼體制,又稱為單密鑰密碼機(jī)制,其基本特征為加密密鑰和解密密鑰相同。
    的頭像 發(fā)表于 01-04 11:25 ?1738次閱讀
    <b class='flag-5'>對(duì)稱</b><b class='flag-5'>加密</b>算法工作模式詳解

    使用go語(yǔ)言實(shí)現(xiàn)一個(gè)grpc攔截器

    在開(kāi)發(fā)grpc服務(wù)時(shí),我們經(jīng)常會(huì)遇到一些通用的需求,比如:日志、鏈路追蹤、鑒權(quán)等。這些需求可以通過(guò)grpc攔截器來(lái)實(shí)現(xiàn)。本文使用go語(yǔ)言來(lái)實(shí)現(xiàn)一個(gè) grpc一元模式(Unary)攔截器,上報(bào)鏈路追蹤信息。
    的頭像 發(fā)表于 12-18 10:13 ?574次閱讀
    使用<b class='flag-5'>go</b><b class='flag-5'>語(yǔ)言</b>實(shí)現(xiàn)一個(gè)grpc攔截器

    消除VCR電阻電壓系數(shù)影響,你該怎么做

    消除VCR電阻電壓系數(shù)影響,你該怎么做
    的頭像 發(fā)表于 12-15 16:40 ?508次閱讀
    消除VCR電阻電壓系數(shù)影響,你該<b class='flag-5'>怎么做</b>?

    加密芯片工作原理max32555

    、實(shí)現(xiàn)方式和安全性等方面。 一、加密芯片的功能 數(shù)據(jù)加密加密芯片采用對(duì)稱或非對(duì)稱加密算法,對(duì)數(shù)
    的頭像 發(fā)表于 12-13 15:03 ?1863次閱讀

    Go編程語(yǔ)言-你應(yīng)該知道的一切

    Go 編程語(yǔ)言的故事始于 Google,當(dāng)時(shí)三位工程師 Robert Griesemer、Rob Pike 和 Ken Thompson 對(duì) C++ 的復(fù)雜性以及缺乏提供高效編譯和執(zhí)行的簡(jiǎn)單語(yǔ)言感到厭倦。
    的頭像 發(fā)表于 12-11 17:37 ?558次閱讀

    php加密方式有哪些

    PHP加密方式有許多種,以下是一些常用的加密方式: 對(duì)稱加密 對(duì)稱加密算法使用相同的密鑰進(jìn)行
    的頭像 發(fā)表于 12-04 15:32 ?578次閱讀

    求助,關(guān)于EEPROM存數(shù)據(jù)加密問(wèn)題

    讀了一個(gè)eeprom,已知(00 0E 00 24 AC BD 00 20 AA BE 00 00 38 DD 3E D4)與編號(hào)014557有關(guān)系,這個(gè)加密算法是怎么做
    發(fā)表于 11-10 07:02

    什么是FIB?FIB有哪些應(yīng)用?如何修改線路FIB?FIB怎么做失效分析?

    什么是FIB?FIB有哪些應(yīng)用?如何修改線路FIB?FIB怎么做失效分析?FIB還能生長(zhǎng)PAD?FIB案例有些? FIB是Focused Ion Beam(聚焦離子束)的縮寫(xiě),是一種利用離子束刻蝕
    的頭像 發(fā)表于 11-07 10:35 ?3392次閱讀

    Go語(yǔ)言比Python強(qiáng)多少

    1.都說(shuō)Go語(yǔ)言性能非常強(qiáng)大,那么到底比Python強(qiáng)多少? 為了比較Go語(yǔ)言和Python語(yǔ)言在單線程性能上的差距,我們可以做一個(gè)簡(jiǎn)單實(shí)驗(yàn)
    的頭像 發(fā)表于 11-02 14:05 ?481次閱讀
    <b class='flag-5'>Go</b><b class='flag-5'>語(yǔ)言</b>比Python強(qiáng)多少

    如何讓Python和Go互相調(diào)度

    我們?cè)?jīng)研究過(guò)如何讓Python和Go互相調(diào)度,當(dāng)時(shí)發(fā)現(xiàn),將Go語(yǔ)言寫(xiě)的模塊打包成動(dòng)態(tài)鏈接庫(kù),就能在Python中進(jìn)行調(diào)度: 優(yōu)劣互補(bǔ)! Python+Go結(jié)合開(kāi)發(fā)的探討
    的頭像 發(fā)表于 11-02 11:24 ?510次閱讀
    如何讓Python和<b class='flag-5'>Go</b>互相調(diào)度