golang 密碼學-2. 非對稱加密

wangchunbo發表於2020-05-25

golang 密碼學-2. 非對稱加密

非對稱加密

1. 對稱加密的弊端

  • 祕鑰分發困難

  • 可以通過非對稱加密完成祕鑰的分發

https

Alice 和 Bob通訊, Alice給bob傳送資料, 使用對稱加密的方式

  1. 生成一個非對稱的祕鑰對, bob生成
  1. bob將公鑰傳送給alice
  1. alice生成一個用於對稱加密的祕鑰
  1. alice使用bob的公鑰就對稱加密的祕鑰進行加密, 並且傳送給bob
  1. bob使用私鑰就資料解密, 得到對稱加密的祕鑰
  1. 通訊的雙方使用寫好的祕鑰進行對稱加密資料加密

2. 非對稱加密的祕鑰

  • 不存在祕鑰分發困難的問題

2.1 場景分析

資料對誰更重要, 誰就拿私鑰

  • 直觀上看: 私鑰比公鑰長

  • 使用第三方工具生成金鑰對: 公鑰檔案xxx.pub xxx

  1. 通訊流程, 資訊加密 (A寫資料, 傳送給B, 資訊只允許B讀)

A: 公鑰

B: 私鑰

  1. 登入認證 (客戶端要登入, 連線伺服器, 向伺服器請求個人資料)

客戶端: 私鑰

伺服器: 公鑰

  1. 數字簽名(表明資訊沒有受到偽造,確實是資訊擁有者發出來的,附在資訊原文的後面)
  • 傳送資訊的人: 私鑰
  • 收到資訊的人: 公鑰
  1. 網銀U盾
  • 個人: 私鑰
  • 銀行拿公鑰

3. 使用RSA非對稱加密通訊流程

要求: Alice 給 bob傳送資料, 保證資料資訊只有bob能看到

4. 生成RSA的祕鑰對

4.1 一些概念

  1. x509證照規範、pem、base64
  • pem編碼規範 - 資料加密

  • base64 - 對資料編碼, 可逆

  • 不管原始資料是什麼, 將原始資料使用64個字元來替代

  • a-z A-Z 0-9 + /

  1. ASN.1抽象語法標記

  2. PKCS1標準

4.2 金鑰對生成流程

  • 生成私鑰操作流程概述
  1. 使用rsa中的GenerateKey方法生成私鑰

func GenerateKey(random io.Reader, bits int) (priv *PrivateKey, err error)

  • rand.Reader -> import “crypto/rand”
  • 1024 的整數倍 - 建議
  1. 通過x509標準將得到的ras私鑰序列化為ASN.1 的 DER編碼字串

func MarshalPKCS1PrivateKey(key *rsa.PrivateKey) []byte

  1. 將私鑰字串設定到pem格式塊中

初始化一個pem.Block塊


  type  Block  struct {

  Type string  // 得自前言的型別(如"RSA PRIVATE KEY")

  Headers map[string]string  // 可選的頭項

  Bytes []byte  // 內容解碼後的資料,一般是DER編碼的ASN.1結構

  }
  1. 通過pem將設定好的資料進行編碼, 並寫入磁碟檔案中

func Encode(out io.Writer, b *Block) error

  • out - 準備一個檔案指標
  • 生成公鑰操作流程
  1. 從得到的私鑰物件中將公鑰資訊取出
  type  PrivateKey  struct {

  PublicKey // 公鑰

  D *big.Int // 私有的指數

  Primes []*big.Int // N的素因子,至少有兩個

  // 包含預先計算好的值,可在某些情況下加速私鑰的操作

  Precomputed PrecomputedValues

  }
  1. 通過x509標準將得到 的rsa公鑰序列化為字串

 func MarshalPKIXPublicKey(pub interface{}) ([]byte, error)
  1. 將公鑰字串設定到pem格式塊中

 type Block struct {

 Type string // 得自前言的型別(如"RSA PRIVATE KEY")

 Headers map[string]string // 可選的頭項

 Bytes []byte // 內容解碼後的資料,一般是DER編碼的ASN.1結構

 }
  1. 通過pem將設定好的資料進行編碼, 並寫入磁碟檔案

func Encode(out io.Writer, b *Block) error

5. RSA加解密

5.1 RSA加密

  1. 將公鑰檔案中的公鑰讀出, 得到使用pem編碼的字串

– 讀檔案

  1. 將得到的字串解碼

– pem.Decode

  1. 使用x509將編碼之後的公鑰解析出來

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

  1. 使用得到的公鑰通過rsa進行資料加密

5.2 RSA解密

  1. 將私鑰檔案中的私鑰讀出, 得到使用pem編碼的字串

  2. 將得到的字串解碼

  3. 使用x509將編碼之後的私鑰解析出來

  4. 使用得到的私鑰通過rsa進行資料解密

6. 雜湊演算法

6.1 概念

稱謂: 單向雜湊函式, 雜湊函式, 雜湊函式, 訊息摘要函式

接收的輸入: 原像

輸出: 雜湊值, 雜湊值, 指紋, 摘要

6.2 單向雜湊函式特性

  1. 將任意長度的資料轉換成固定長度的資料

  2. 很強的抗碰撞性

  3. 不可逆

  4. MD4/MD5

  • 不安全

  • 雜湊值長度: 128bit == 16byte

  1. sha1
  • 不安全

  • 雜湊值長度: 160bit == 20byte

  1. sha2 - 安全
  • sha224

  • 雜湊值長度: 224bit == 28byte

  • sha256

  • 雜湊值長度: 256== 32byte

  • sha384

  • 雜湊值長度: 384bit == 48byte

  • sha512

  • 雜湊值長度: 512bit == 64byte

6.3 go中使用單向雜湊函式


// 第一種方式, 直接呼叫sum

// 適用於資料量比較小的情況

func  Sum(data []byte) [Size]byte

// 第二種方式

// 1. 建立雜湊介面物件

func  New() hash.Hash

type  Hash  interface {

// 通過嵌入的匿名io.Writer介面的Write方法向hash中新增更多資料,永遠不返回錯誤

io.Writer

// 返回新增b到當前的hash值後的新切片,不會改變底層的hash狀態

Sum(b []byte) []byte

// 重設hash為無資料輸入的狀態

Reset()

// 返回Sum會返回的切片的長度

Size() int

// 返回hash底層的塊大小;Write方法可以接受任何大小的資料,

// 但提供的資料是塊大小的倍數時效率更高

BlockSize() int

}

type  Writer  interface {

Write(p []byte) (n int, err error)

}

// 2. 往建立出的雜湊物件中新增資料

hash.Hash.Write([]byte("新增的資料..."))

hash.Hash.Write([]byte("新增的資料..."))

hash.Hash.Write([]byte("新增的資料..."))

hash.Hash.Write([]byte("新增的資料..."))

// 3. 計算結果, md5就是雜湊值

md5 := hash.Sum(nil);

// 雜湊值一般是一個二進位制的字串, 有些字元不可見, 需要格式化

// 格式化為16進位制的數字串 - 0-9, a-f

func  EncodeToString(src []byte) string

// 資料轉換完成之後, 長度是原來的2倍
  1. 計算一個大檔案比如1G檔案的雜湊值

  2. 使用udp的方式分發祕鑰, 進行一個對稱加密的通訊

  • 伺服器

  • 生成金鑰對

  • 公鑰傳送給客戶端

  • 客戶端

  • 客戶端收到了公鑰

  • 生成一個祕鑰 - 用於對稱加密

  • 使用公鑰加密, 傳送給伺服器

複習

  1. 概念
  • 加密三要素

  • 明文/密文

  • 祕鑰

  • 演算法

  • 對稱加密和非對稱加密

  • 對稱加密: 加解密使用同一個祕鑰, 1個

  • 效率高

  • 非…: 金鑰對

  • 公鑰加密, 私鑰解密

  • 私鑰加密, 公鑰解密

  • 對稱加密中的公開的加密演算法

  • des

  • 分組長度: 8位元組

  • 祕鑰長度: 8位元組

  • 3des

  • 分組長度: 8位元組

  • 祕鑰長度: 24byte

  • aes

  • 分組長度: 16位元組

  • 祕鑰長度: 16位元組, 24位元組, 32位元組

  • 在go的api中只能使用16位元組

  • 對稱加密的分組模式

  • EBC - 不推薦使用

  • CBC - 常用的方式

  • 準備的資料:

  • 初始化向量iv - 字元陣列

  • 長度 == 明文分組長度

  • 加解密初始化向量值必須相同

  • 祕鑰

  • 根據加密演算法定

===========================

  • OFB - 不推薦使用

  • CFB - 不推薦使用

  • CTR - 推薦使用, 效率最高

禁止 學習某地爬蟲,知乎爬蟲,CSDN 爬蟲。

本文,首發在 learnku 社群。

@author
汪春波(www.shxdledu.cn)

本作品採用《CC 協議》,轉載必須註明作者和本文連結

上海PHP自學中心-免費程式設計視訊教學|
7Dn78VKKcW.jpg!large
S3d25uqwht.png!large

相關文章