跟語(yǔ)言無(wú)關(guān),跟加密算法有關(guān)。你如果調(diào)用公開的算法,用同樣的算子去加密解密,那用哪種需要都一樣,關(guān)鍵就是很多算法都有你不了解的細(xì)節(jié),有些算子是編程語(yǔ)言自己用了默認(rèn)值,而他們彼此不同
創(chuàng)新互聯(lián)公司專注于網(wǎng)站建設(shè),為客戶提供成都網(wǎng)站制作、成都做網(wǎng)站、外貿(mào)營(yíng)銷網(wǎng)站建設(shè)、網(wǎng)頁(yè)設(shè)計(jì)開發(fā)服務(wù),多年建網(wǎng)站服務(wù)經(jīng)驗(yàn),各類網(wǎng)站都可以開發(fā),成都品牌網(wǎng)站建設(shè),公司官網(wǎng),公司展示網(wǎng)站,網(wǎng)站設(shè)計(jì),建網(wǎng)站費(fèi)用,建網(wǎng)站多少錢,價(jià)格優(yōu)惠,收費(fèi)合理。
本篇文章中,將描述如何使用go創(chuàng)建CA,并使用CA簽署證書。在使用openssl創(chuàng)建證書時(shí),遵循的步驟是 創(chuàng)建秘鑰 創(chuàng)建CA 生成要頒發(fā)證書的秘鑰 使用CA簽發(fā)證書。這種步驟,那么我們現(xiàn)在就來(lái)嘗試下。
首先,會(huì)從將從創(chuàng)建 CA 開始。 CA 會(huì)被用來(lái)簽署其他證書
接下來(lái)需要對(duì)證書生成公鑰和私鑰
然后生成證書:
我們看到的證書內(nèi)容是PEM編碼后的,現(xiàn)在 caBytes 我們有了生成的證書,我們將其進(jìn)行 PEM 編碼以供以后使用:
證書的 x509.Certificate 與CA的 x509.Certificate 屬性有稍微不同,需要進(jìn)行一些修改
為該證書創(chuàng)建私鑰和公鑰:
有了上述的內(nèi)容后,可以創(chuàng)建證書并用CA進(jìn)行簽名
要保存成證書格式需要做PEM編碼
創(chuàng)建一個(gè) ca.go 里面是創(chuàng)建ca和頒發(fā)證書的邏輯
如果需要使用的話,可以引用這些函數(shù)
panic: x509: unsupported public key type: rsa.PublicKey
這里是因?yàn)? x509.CreateCertificate 的參數(shù) privatekey 需要傳入引用變量,而傳入的是一個(gè)普通變量
extendedKeyUsage :增強(qiáng)型密鑰用法(參見(jiàn)"new_oids"字段):服務(wù)器身份驗(yàn)證、客戶端身份驗(yàn)證、時(shí)間戳。
keyUsage : 密鑰用法,防否認(rèn)(nonRepudiation)、數(shù)字簽名(digitalSignature)、密鑰加密(keyEncipherment)。
文章來(lái)自
加密的原因:保證數(shù)據(jù)安全
加密必備要素:1、明文/密文? ? 2、秘鑰? ? 3、算法
秘鑰:在密碼學(xué)中是一個(gè)定長(zhǎng)的字符串、需要根據(jù)加密算法確定其長(zhǎng)度
加密算法解密算法一般互逆、也可能相同
常用的兩種加密方式:
對(duì)稱加密:秘鑰:加密解密使用同一個(gè)密鑰、數(shù)據(jù)的機(jī)密性雙向保證、加密效率高、適合加密于大數(shù)據(jù)大文件、加密強(qiáng)度不高(相對(duì)于非對(duì)稱加密)
非對(duì)稱加密:秘鑰:加密解密使用的不同秘鑰、有兩個(gè)密鑰、需要使用密鑰生成算法生成兩個(gè)秘鑰、數(shù)據(jù)的機(jī)密性只能單向加密、如果想解決這個(gè)問(wèn)題、雙向都需要各自有一對(duì)秘鑰、加密效率低、加密強(qiáng)度高
??? ??? ?? ? 公鑰:可以公開出來(lái)的密鑰、公鑰加密私鑰解密
??? ??? ?? ? 私鑰:需要自己妥善保管、不能公開、私鑰加密公鑰解密
安全程度高:多次加密
按位異或運(yùn)算
凱撒密碼:加密方式? ? 通過(guò)將銘文所使用的字母表按照一定的字?jǐn)?shù)平移來(lái)進(jìn)行加密
mod:取余
加密三要素:明文/密文(字母)、秘鑰(3)、算法(向右平移3/-3)
安全常識(shí):不要使用自己研發(fā)的算法、不要鉆牛角尖、沒(méi)必要研究底層實(shí)現(xiàn)、了解怎么應(yīng)用;低強(qiáng)度的密碼比不進(jìn)行任何加密更危險(xiǎn);任何密碼都會(huì)被破解;密碼只是信息安全的一部分
保證數(shù)據(jù)的機(jī)密性、完整性、認(rèn)證、不可否認(rèn)性
計(jì)算機(jī)操作對(duì)象不是文字、而是由0或1排列而成的比特序列、程序存儲(chǔ)在磁盤是二進(jìn)制的字符串、為比特序列、將現(xiàn)實(shí)的東西映射為比特序列的操作稱為編碼、加密又稱之為編碼、解密稱之為解碼、根據(jù)ASCII對(duì)照表找到對(duì)應(yīng)的數(shù)字、轉(zhuǎn)換成二進(jìn)制
三種對(duì)稱加密算法:DES\3DES\ AES??
DES:已經(jīng)被破解、除了用它來(lái)解密以前的明文、不再使用
密鑰長(zhǎng)度為56bit/8、為7byte、每隔7個(gè)bit會(huì)設(shè)置一個(gè)用于錯(cuò)誤檢查的比特、因此實(shí)際上是64bit
分組密碼(以組為單位進(jìn)行處理):加密時(shí)是按照一個(gè)單位進(jìn)行加密(8個(gè)字節(jié)/64bit為一組)、每一組結(jié)合秘鑰通過(guò)加密算法得到密文、加密后的長(zhǎng)度不變
3DES:三重DES為了增加DES的強(qiáng)度、將DES重復(fù)三次所得到的一種加密算法? ?密鑰長(zhǎng)度24byte、分成三份? 加密--解密--加密 目的:為了兼容DES、秘鑰1秘鑰2相同==三個(gè)秘鑰相同? ---加密一次?? ?? ? 密鑰1秘鑰3相同--加密三次? ? 三個(gè)密鑰不相同最好、此時(shí)解密相當(dāng)于加密、中間的一次解密是為了有三個(gè)密鑰相同的情況
此時(shí)的解密操作與加密操作互逆,安全、效率低
數(shù)據(jù)先解密后加密可以么?可以、解密相當(dāng)于加密、加密解密說(shuō)的是算法
AES:(首選推薦)底層算法為Rijndael? ?分組長(zhǎng)度為128bit、密鑰長(zhǎng)度為128bit到256bit范圍內(nèi)就可以? ?但是在AES中、密鑰長(zhǎng)度只有128bit\192bit\256bit?? ??在go提供的接口中、只能是16字節(jié)(128bit)、其他語(yǔ)言中秘鑰可以選擇
目前為止最安全的、效率高
底層算法
分組密碼的模式:
按位異或、對(duì)數(shù)據(jù)進(jìn)行位運(yùn)算、先將數(shù)據(jù)轉(zhuǎn)換成二進(jìn)制、按位異或操作符^、相同為真、不同為假、非0為假? ? 按位異或一次為加密操作、按位異或兩次為解密操作:a和b按位異或一次、結(jié)果再和b按位異或
ECB?: 如果明文有規(guī)律、加密后的密文有規(guī)律不安全、go里不提供該接口、明文分組分成固定大小的塊、如果最后一個(gè)分組不滿足分組長(zhǎng)度、則需要補(bǔ)位
CBC:密碼鏈
問(wèn)題:如何對(duì)字符串進(jìn)行按位異或?解決了ECB的規(guī)律可查缺點(diǎn)、但是他不能并行處理、最后一個(gè)明文分組也需要填充 、初始化向量長(zhǎng)度與分組長(zhǎng)度相同
CFB:密文反饋模式
不需要填充最后一個(gè)分組、對(duì)密文進(jìn)行加密
OFB:
不需要對(duì)最后一組進(jìn)行填充
CTR計(jì)數(shù)器:
不需要對(duì)最后一組進(jìn)行填充、不需要初始化向量??? ?
Go中的實(shí)現(xiàn)
官方文檔中:
在創(chuàng)建aes或者是des接口時(shí)都是調(diào)用如下的方法、返回的block為一個(gè)接口
func NewCipher(key [] byte ) ( cipher . Block , error )
type Block interface {
// 返回加密字節(jié)塊的大小
BlockSize() int
// 加密src的第一塊數(shù)據(jù)并寫入dst,src和dst可指向同一內(nèi)存地址
Encrypt(dst, src []byte)
// 解密src的第一塊數(shù)據(jù)并寫入dst,src和dst可指向同一內(nèi)存地址
Decrypt(dst, src []byte)
}
Block接口代表一個(gè)使用特定密鑰的底層塊加/解密器。它提供了加密和解密獨(dú)立數(shù)據(jù)塊的能力。
Block的Encrypt/Decrypt也能進(jìn)行加密、但是只能加密第一組、因?yàn)閍es的密鑰長(zhǎng)度為16、所以進(jìn)行操作的第一組數(shù)據(jù)長(zhǎng)度也是16
如果分組模式選擇的是cbc
func NewCBCEncrypter(b Block, iv []byte) BlockMode? ? 加密
func NewCBCDecrypter(b Block, iv []byte) BlockMode? ? 解密
加密解密都調(diào)用同一個(gè)方法CryptBlocks()
并且cbc分組模式都會(huì)遇到明文最后一個(gè)分組的補(bǔ)充、所以會(huì)用到加密字節(jié)的大小
返回一個(gè)密碼分組鏈接模式的、底層用b加密的BlockMode接口,初始向量iv的長(zhǎng)度必須等于b的塊尺寸。iv自己定義
返回的BlockMode同樣也是一個(gè)接口類型
type BlockMode interface {
// 返回加密字節(jié)塊的大小
BlockSize() int
// 加密或解密連續(xù)的數(shù)據(jù)塊,src的尺寸必須是塊大小的整數(shù)倍,src和dst可指向同一內(nèi)存地址
CryptBlocks(dst, src []byte)
}
BlockMode接口代表一個(gè)工作在塊模式(如CBC、ECB等)的加/解密器
返回的BlockMode其實(shí)是一個(gè)cbc的指針類型中的b和iv
# 加密流程:?
1. 創(chuàng)建一個(gè)底層使用des/3des/aes的密碼接口 "crypto/des" func NewCipher(key []byte) (cipher.Block, error) # -- des func NewTripleDESCipher(key []byte) (cipher.Block, error) # -- 3des "crypto/aes" func NewCipher(key []byte) (cipher.Block, error) # == aes?
2. 如果使用的是cbc/ecb分組模式需要對(duì)明文分組進(jìn)行填充
3. 創(chuàng)建一個(gè)密碼分組模式的接口對(duì)象 - cbc func NewCBCEncrypter(b Block, iv []byte) BlockMode # 加密 - cfb func NewCFBEncrypter(block Block, iv []byte) Stream # 加密 - ofb - ctr
4. 加密, 得到密文
流程:
填充明文:
先求出最后一組中的字節(jié)數(shù)、創(chuàng)建新切片、長(zhǎng)度為新切片、值也為切片的長(zhǎng)度、然后利用bytes.Reapet將長(zhǎng)度換成字節(jié)切片、追加到原明文中
//明文補(bǔ)充
func padPlaintText(plaintText []byte,blockSize int)[]byte{
//1、求出需要填充的個(gè)數(shù)
padNum := blockSize-len(plaintText) % blockSize
//2、對(duì)填充的個(gè)數(shù)進(jìn)行操作、與原明文進(jìn)行合并
newPadding := []byte{byte(padNum)}
newPlain := bytes.Repeat(newPadding,padNum)
plaintText = append(plaintText,newPlain...)
return plaintText
}
去掉填充數(shù)據(jù):
拿去切片中的最后一個(gè)字節(jié)、得到尾部填充的字節(jié)個(gè)數(shù)、截取返回
//解密后的明文曲調(diào)補(bǔ)充的地方
func createPlaintText(plaintText []byte,blockSize int)[]byte{
//1、得到最后一個(gè)字節(jié)、并將字節(jié)轉(zhuǎn)換成數(shù)字、去掉明文中此數(shù)字大小的字節(jié)
padNum := int(plaintText[len(plaintText)-1])
newPadding := plaintText[:len(plaintText)-padNum]
return newPadding
}
des加密:
1、創(chuàng)建一個(gè)底層使用des的密碼接口、參數(shù)為秘鑰、返回一個(gè)接口
2、對(duì)明文進(jìn)行填充
3、創(chuàng)建一個(gè)cbc模式的接口、需要?jiǎng)?chuàng)建iv初始化向量、返回一個(gè)blockmode對(duì)象
4、加密、調(diào)用blockmode中的cryptBlock函數(shù)進(jìn)行加密、參數(shù)為目標(biāo)參數(shù)和源參數(shù)
//des利用分組模式cbc進(jìn)行加密
func EncryptoText(plaintText []byte,key []byte)[]byte{
//1、創(chuàng)建des對(duì)象
cipherBlock,err := des.NewCipher(key)
if err != nil {
panic(err)
}
//2、對(duì)明文進(jìn)行填充
newText := padPlaintText(plaintText,cipherBlock.BlockSize())
//3、選擇分組模式、其中向量的長(zhǎng)度必須與分組長(zhǎng)度相同
iv := make([]byte,cipherBlock.BlockSize())
blockMode := cipher.NewCBCEncrypter(cipherBlock,iv)
//4、加密
blockMode.CryptBlocks(newText,newText)
return newText
}
des解密:
1、創(chuàng)建一個(gè)底層使用des的密碼接口、參數(shù)為秘鑰、返回一個(gè)接口
2、創(chuàng)建一個(gè)cbc模式的接口、需要?jiǎng)?chuàng)建iv初始化向量,返回一個(gè)blockmode對(duì)象
3、加密、調(diào)用blockmode中的cryptBlock函數(shù)進(jìn)行解密、參數(shù)為目標(biāo)參數(shù)和源參數(shù)
4、調(diào)用去掉填充數(shù)據(jù)的方法
//des利用分組模式cbc進(jìn)行解密
func DecryptoText(cipherText []byte, key []byte)[]byte{
//1、創(chuàng)建des對(duì)象
cipherBlock,err := des.NewCipher(key)
if err != nil {
panic(err)
}
//2、創(chuàng)建cbc分組模式接口
iv := []byte("12345678")
blockMode := cipher.NewCBCDecrypter(cipherBlock,iv)
//3、解密
blockMode.CryptBlocks(cipherText,cipherText)
//4、將解密后的數(shù)據(jù)進(jìn)行去除填充的數(shù)據(jù)
newText := clearPlaintText(cipherText,cipherBlock.BlockSize())
return newText
}
Main函數(shù)調(diào)用
func main(){
//需要進(jìn)行加密的明文
plaintText := []byte("CBC--密文沒(méi)有規(guī)律、經(jīng)常使用的加密方式,最后一個(gè)分組需要填充,需要初始化向量" +
"(一個(gè)數(shù)組、數(shù)組的長(zhǎng)度與明文分組相等、數(shù)據(jù)來(lái)源:負(fù)責(zé)加密的人提供,加解密使用的初始化向量必須相同)")
//密鑰Key的長(zhǎng)度需要與分組長(zhǎng)度相同、且加密解密的密鑰相同
key := []byte("1234abcd")
//調(diào)用加密函數(shù)
cipherText := EncryptoText(plaintText,key)
newPlaintText := DecryptoText(cipherText,key)
fmt.Println(string(newPlaintText))
}
AES加密解密相同、所以只需要調(diào)用一次方法就可以加密、調(diào)用兩次則解密
推薦是用分組模式:cbc、ctr
aes利用分組模式cbc進(jìn)行加密
//對(duì)明文進(jìn)行補(bǔ)充
func paddingPlaintText(plaintText []byte , blockSize int ) []byte {
//1、求出分組余數(shù)
padNum := blockSize - len(plaintText) % blockSize
//2、將余數(shù)轉(zhuǎn)換為字節(jié)切片、然后利用bytes.Repeat得出有該余數(shù)的大小的字節(jié)切片
padByte := bytes.Repeat([]byte{byte(padNum)},padNum)
//3、將補(bǔ)充的字節(jié)切片添加到原明文中
plaintText = append(plaintText,padByte...)
return plaintText
}
//aes加密
func encryptionText(plaintText []byte, key []byte) []byte {
//1、創(chuàng)建aes對(duì)象
block,err := aes.NewCipher(key)
if err != nil {
panic(err)
}
//2、明文補(bǔ)充
newText := paddingPlaintText(plaintText,block.BlockSize())
//3、創(chuàng)建cbc對(duì)象
iv := []byte("12345678abcdefgh")
blockMode := cipher.NewCBCEncrypter(block,iv)
//4、加密
blockMode.CryptBlocks(newText,newText)
return newText
}
//解密后的去尾
func clearplaintText(plaintText []byte, blockSize int) []byte {
//1、得到最后一個(gè)字節(jié)、并轉(zhuǎn)換成整型數(shù)據(jù)
padNum := int(plaintText[len(plaintText)-1])
//2、截取明文字節(jié)中去掉得到的整型數(shù)據(jù)之前的數(shù)據(jù)、此處出錯(cuò)、沒(méi)有用len-padNum
newText := plaintText[:len(plaintText)-padNum]
return newText
}
//aes解密
func deCryptionText(crypherText []byte, key []byte ) []byte {
//1、創(chuàng)建aes對(duì)象
block, err := aes.NewCipher(key)
if err != nil {
panic(err)
}
//2、創(chuàng)建cbc對(duì)象
iv := []byte("12345678abcdefgh")
blockMode := cipher.NewCBCDecrypter(block,iv)
//3、解密
blockMode.CryptBlocks(crypherText,crypherText)
//4、去尾
newText := clearplaintText(crypherText,block.BlockSize())
return newText
}
func main(){
//需要進(jìn)行加密的明文
plaintText := []byte("CBC--密文沒(méi)有規(guī)律、經(jīng)常使用的加密方式,最后一個(gè)分組需要填充,需要初始化向量")
//密鑰Key的長(zhǎng)度需要與分組長(zhǎng)度相同、且加密解密的密鑰相同
key := []byte("12345678abcdefgh")
//調(diào)用加密函數(shù)
cipherText := encryptionText(plaintText,key)
//調(diào)用解密函數(shù)
newPlaintText := deCryptionText(cipherText,key)
fmt.Println("解密后",string(newPlaintText))
}
//aes--ctr加密
func encryptionCtrText(plaintText []byte, key []byte) []byte {
//1、創(chuàng)建aes對(duì)象
block,err := aes.NewCipher(key)
if err != nil {
panic(err)
}
//2、創(chuàng)建ctr對(duì)象,雖然ctr模式不需要iv,但是go中使用ctr時(shí)還是需要iv
iv := []byte("12345678abcdefgh")
stream := cipher.NewCTR(block,iv)
stream.XORKeyStream(plaintText,plaintText)
return plaintText
}
func main() {
//aes--ctr加密解密、調(diào)用兩次即為解密、因?yàn)榧用芙饷芎瘮?shù)相同stream.XORKeyStream
ctrcipherText := encryptionCtrText(plaintText, key)
ctrPlaintText := encryptionCtrText(ctrcipherText,key)
fmt.Println("aes解密后", string(ctrPlaintText))
}
英文單詞:
明文:plaintext? ? ?密文:ciphertext? ?填充:padding/fill? ? 去掉clear? 加密Encryption? 解密Decryption
func ReadBytes(path string) ([]byte, error) {
f, err := os.Open(path)
if err != nil {
return nil, err
}
defer f.Close()
return ioutil.ReadAll(f)
}
func RSAEncrypt(data []byte) ([]byte, error) {
publicKey, err := ReadBytes(`public.pem`)
if err != nil {
return nil, err
}
block, _ := pem.Decode(publicKey)
if block == nil {
return nil, errors.New("public key error")
}
pubInterface, err := x509.ParsePKIXPublicKey(block.Bytes)
if err != nil {
return nil, err
}
return rsa.EncryptPKCS1v15(rand.Reader, pubInterface.(*rsa.PublicKey), data)
}
func RSADecrypt(data []byte) ([]byte, error) {
privateKey, err := ReadBytes(`private.pem`)
if err != nil {
return nil, err
}
block, _ := pem.Decode(privateKey)
if block == nil {
return nil, errors.New("private key error")
}
priv, err := x509.ParsePKCS1PrivateKey(block.Bytes)
if err != nil {
return nil, err
}
return rsa.DecryptPKCS1v15(rand.Reader, priv, data)
}
其中public.pem是公鑰文件,private.pem是私鑰文件。
當(dāng)前名稱:go語(yǔ)言證書私鑰加密,golang 密碼加密
當(dāng)前路徑:http://jinyejixie.com/article34/hojjse.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供企業(yè)建站、、品牌網(wǎng)站制作、微信公眾號(hào)、微信小程序、小程序開發(fā)
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)