Goの暗号化と復号化アルゴリズムの概要

Goの暗号化と復号化アルゴリズムの概要

[[343693]]

序文

実際の開発では、暗号化と復号化が広く使用されています。一般的に使用される暗号化と復号化は、「対称」、「非対称」、「デジタル署名」に分けられます。

対称: 対称暗号化 (秘密鍵暗号化とも呼ばれる) は、暗号化と復号化に同じ鍵を使用する暗号化アルゴリズムを指します。具体的なアルゴリズムには、DES アルゴリズム、3DES アルゴリズム、TDEA アルゴリズム、Blowfish アルゴリズム、RC5 アルゴリズム、IDEA アルゴリズムなどがあります。

非対称暗号化 (公開鍵暗号化): 暗号化と復号化に異なる鍵を使用する暗号化アルゴリズムを指します。公開鍵暗号化とも呼ばれます。具体的なアルゴリズムとしては、RSA、Elgamal、バックパックアルゴリズム、Rabin、DH、ECC(楕円曲線暗号化アルゴリズム)などがあります。

デジタル署名: デジタル署名は、非対称キー暗号化技術とデジタル要約技術の応用です。主なアルゴリズムには、md5、hmac、sha1 などがあります。

以下では、golang 言語の主な暗号化および復号化アルゴリズムの実装を紹介します。

MD5

MD5 メッセージ ダイジェスト アルゴリズムは、情報伝送の整合性と一貫性を確保するために 128 ビット (16 進数、32 文字) のハッシュ値を生成できる、広く使用されている暗号化ハッシュ関数です。

  1. GetMd5String関数(文字列)文字列{
  2. h : = md5.New ()です。
  3.   h.Write([]バイト)  
  4. hex.EncodeToString(h.Sum(nil)) を返す 
  5. }

hmac

HMAC は、ハッシュベースのメッセージ認証コードの略です。

ハッシュ計算プロセス中にキーを計算プロセスに組み込むために標準アルゴリズムを使用します。

当社のカスタム ソルト アルゴリズムとは異なり、Hmac アルゴリズムは、MD5 または SHA-1 を問わず、すべてのハッシュ アルゴリズムに共通です。独自のソルト アルゴリズムの代わりに Hmac を使用すると、プログラム アルゴリズムをより標準化し、より安全にすることができます。

  1. //キーは任意に設定可能で、データを暗号化するデータ 
  2. func Hmac(キー, データ文字列) 文字列 {
  3. hash: = hmac .New(md5.New, []byte(key)) // 対応するmd5ハッシュ暗号化アルゴリズムを作成する 
  4. ハッシュ.Write([]byte(データ))
  5. hex.EncodeToString(hash.Sum([]byte(""))) を返します
  6. }  
  7. func HmacSha256(キー、データ文字列) 文字列 {  
  8. hash: = hmac .New(sha256.New, []byte(key)) //対応するsha256ハッシュ暗号化アルゴリズムを作成する 
  9. ハッシュ.Write([]byte(データ))  
  10. hex.EncodeToString(hash.Sum([]byte(""))) を返します 
  11. }

シャ1

SHA-1 は、メッセージ ダイジェストと呼ばれる 160 ビット (20 バイト) のハッシュ値を生成します。これは通常、40 桁の 16 進数として表されます。

  1. func Sh​​a1(データ文字列) 文字列 {
  2. sha1 : = sha1.New () です。
  3. sha1.Write([]バイト(データ))  
  4. hex.EncodeToString(sha1.Sum([]byte(""))) を返します。  
  5. }

エーエス

暗号化における Advanced Encryption Standard (AES) は、Rijndael 暗号化とも呼ばれ、米国連邦政府が採用しているブロック暗号化標準です。この標準は、元の DES (データ暗号化標準) に代わるものとして使用され、多くの関係者によって分析され、世界中で広く使用されています。 AES には、AES-128、AES-192、AES-256 という 3 つの一般的なソリューションがあります。真の 128 ビット暗号化、あるいは 256 ビット暗号化が使用されている場合、ブルート フォース攻撃が成功するにはかなりの時間がかかります。

AES には 5 つの暗号化モードがあります。

  • 電子コードブック(ECB)
  • 暗号ブロック連鎖(CBC)、
  • カウンター(CTR)
  • 暗号フィードバック (CFB)
  • 出力フィードバック (OFB)

ECBモード

セキュリティ上の理由から、golang はデフォルトでは ECB モードをサポートしていません。

  1. パッケージメイン 
  2. 輸入 (  
  3. 「暗号/AES」  
  4. 「fmt」  
  5.  
  6. func AESEncrypt(src []byte, key []byte) (暗号化された[]byte) {  
  7. 暗号、_ : = aes .NewCipher(generateKey(key))  
  8. 長さ: = (len(src) + aes.BlockSize) / aes.BlockSize  
  9. プレーン: = make ([]byte, length*aes.BlockSize)
  10.   コピー(プレーン, src)  
  11. pad : =バイト(len(plain) - len(src))  
  12. i : = len (src); i <   len (プレーン); i++ {  
  13. プレーン[i] = パッド 
  14. }  
  15. 暗号化= make ([]byte, len(plain))  
  16. // グループで暗号化 
  17. bs, be : = 0 、cipher.BlockSize(); bs < = len(src); bs, be = bs +cipher.BlockSize()、be+cipher.BlockSize() {  
  18. cipher.Encrypt(暗号化[bs:be]、プレーン[bs:be])  
  19. }  
  20. 暗号化して返す 
  21. }  
  22. func AESDecrypt(暗号化された[]バイト、キー[]バイト) (復号化された[]バイト) {
  23. 暗号、_ : = aes .NewCipher(generateKey(key))
  24. 復号化= make ([]byte, len(暗号化))  
  25. //
  26.   bsの場合、be : = 0 、cipher.BlockSize(); bs <   len (暗号化済み); bs, be = bs + cipher.BlockSize(), be + cipher.BlockSize() {  
  27. cipher.Decrypt(復号化[bs:be]、暗号化[bs:be])  
  28. }  
  29. トリム: = 0  
  30. len(復号化) > 0 の場合 {  
  31. トリム= len (復号化) - int(復号化[len(復号化)-1])  
  32. }  
  33. 復号化された[:trim]を返す 
  34. }  
  35. 関数generateKey(key []byte) (genKey []byte) {
  36. genKey = make ([]バイト、16)  
  37. コピー(genKey、キー)
  38. i : = 16 の場合、i <   len (キー);  
  39. j : = 0の場合; j <   16 && 私<   len (キー); j, i = j +1, i+1 {  
  40. genKey[j] ^= キー[i]  
  41. }  
  42. }  
  43. genKeyを返す
  44. }  
  45. 関数main() {  
  46. ソース: = "hello world"    
  47. fmt.Println("元の文字:",ソース)  
  48. //16バイトのキー 
  49. キー: = "1443flfsaWfdas"  
  50. encryptCode: = AESEncrypt ([]byte(ソース),[]byte(キー))  
  51. fmt.Println("暗号文:", string(encryptCode))  
  52. decryptCode: = AESDecrypt (encryptCode, []byte(key))  
  53. fmt.Println("復号化:", string(decryptCode))  
  54. }

CBCモード

  1. パッケージメイン
  2. 輸入(  
  3. 「バイト」  
  4. 「暗号/AES」  
  5. 「fmt」
  6. 「暗号」  
  7. 「エンコーディング/base64」  
  8.  
  9. 関数main() {  
  10. orig : = "こんにちは世界"    
  11. キー: = "0123456789012345"    
  12. fmt.Println("元のテキスト:", orig)  
  13. encryptCode : = AesEncrypt (orig, key)  
  14. fmt.Println("暗号文: ", 暗号化コード)  
  15. 復号コード: = AesDecrypt (暗号化コード、キー)
  16. fmt.Println("復号結果:", decryptCode)  
  17. }  
  18. func AesEncrypt(元の文字列、キー文字列) 文字列 {  
  19. // バイト配列に変換 
  20. origData : = []byte(orig)  
  21. k : = []バイト(キー)  
  22. // グループキー
  23. // NewCipher この関数は入力kの長さを16、24、または32に制限します
  24. ブロック、_ : = aes .NewCipher(k)  
  25. // キーブロックの長さを取得する
  26. ブロックサイズ: =ブロック.BlockSize()  
  27. //完全なコード
  28. origData = PKCS7Padding (origData, ブロックサイズ)
  29. // 暗号化モード 
  30. blockMode : = cipher .NewCB​​CEncrypter(block, k[:blockSize])  
  31. // 配列を作成する
  32. cryted : = make ([]byte, len(origData))  
  33. // 暗号化
  34. blockMode.CryptBlocks(暗号化済み、元のデータ)
  35. base64.StdEncoding.EncodeToString(cryted) を返します。  
  36. }  
  37. func AesDecrypt(暗号化された文字列、キー文字列) 文字列 {
  38. // バイト配列に変換 
  39. crytedByte、_ : = base64.StdEncoding.DecodeString (cryted)  
  40. k : = []バイト(キー)
  41. // グループキー
  42. ブロック、_ : = aes .NewCipher(k)  
  43. // キーブロックの長さを取得する 
  44. ブロックサイズ: =ブロック.BlockSize()  
  45. // 暗号化モード 
  46. blockMode : = cipher .NewCB​​CDecrypter(block, k[:blockSize])  
  47. // 配列を作成する 
  48. orig : = make ([]byte, len(crytedByte))  
  49. // 復号化 
  50. blockMode.CryptBlocks(orig, 暗号化バイト)  
  51. // コードを完成させる 
  52. オリジナル= PKCS7UnPadding (オリジナル)  
  53. 文字列を返す(orig)
  54. }
  55. //補足コード 
  56. //AESで暗号化されたデータブロックの長さは128ビット(バイト[16])である必要があり、キーの長さは128ビット(バイト[16])、192ビット(バイト[24])、256ビット(バイト[32])のいずれかになります。  
  57. PKCS7Padding関数(暗号文[]byte, ブロックサイズint) []byte {  
  58. パディング: =ブロックサイズ- 長さ(暗号文)%ブロックサイズ 
  59. padtext : = bytes .Repeat([]byte{byte(padding)}, padding)  
  60. append(ciphertext, padtext...) を返します 
  61. }  
  62. //デコード 
  63. PKCS7UnPadding関数(origData[]byte)[]byte{  
  64. 長さ: = len (origData)  
  65. アンパディング: = int (origData[length-1])  
  66. origData[:(長さ - パディングなし)] を返す 
  67. }

CRTモード

  1. パッケージメイン 
  2. 輸入 (  
  3. 「バイト」  
  4. 「暗号/AES」  
  5. 「暗号」  
  6. 「fmt」  
  7. //暗号化
  8. func aesCtrCrypt(プレーンテキスト []byte, キー []byte) ([]byte, エラー) {
  9. //1. cipher.Blockインターフェースを作成する
  10. ブロック、エラー: = aes .NewCipher(キー)  
  11. err != nil の場合 {
  12. nil、エラーを返す 
  13. }  
  14. //2. crypto/cipher パッケージでグループ化パターンを作成する
  15. iv : =バイト.Repeat([]byte("1"), block.BlockSize())  
  16. ストリーム: = cipher .NewCTR(ブロック、iv)  
  17. //3. 暗号化 
  18. dst : = make ([]byte, len(プレーンテキスト))
  19. stream.XORKeyStream(dst, プレーンテキスト)  
  20. dst、nil を返す 
  21. }  
  22. 関数main() {
  23. ソース: = "hello world"    
  24. fmt.Println("元の文字:",ソース)  
  25. キー: = "1443flfsaWfdasds"    
  26. encryptCode, _: = aesCtrCrypt ([]byte(ソース),[]byte(キー))  
  27. fmt.Println("暗号文:", string(encryptCode))  
  28. 復号コード、 _: = aesCtrCrypt (暗号化コード、[]byte (キー))  
  29. fmt.Println("復号化:", string(decryptCode))  
  30. }  
  31. CFBモード 
  32. パッケージメイン 
  33. 輸入 (  
  34. 「暗号/AES」  
  35. 「暗号」  
  36. 「暗号/ランド」  
  37. 「エンコーディング/16進数」  
  38. 「fmt」  
  39. 「イオ」  
  40.  
  41. func AesEncryptCFB(origData []byte, key []byte) (暗号化された []byte) {  
  42. ブロック、エラー: = aes .NewCipher(キー)  
  43. err != nil の場合 {  
  44. //パニック(エラー)  
  45. }  
  46. 暗号化= make ([]byte, aes.BlockSize+len(origData))  
  47. iv : =暗号化[:aes.BlockSize]  
  48. _ の場合、 err : = io .ReadFull(rand.Reader, iv); err != nil {  
  49. //パニック(エラー)  
  50. }  
  51. ストリーム: = cipher .NewCFBEncrypter(block, iv)  
  52. stream.XORKeyStream(暗号化[aes.BlockSize:], 元のデータ)  
  53. 暗号化して返す 
  54. }  
  55. func AesDecryptCFB(暗号化された[]バイト、キー[]バイト) (復号化された[]バイト) {  
  56. ブロック、_ : = aes .NewCipher(キー)
  57. len(暗号化) <   aes.ブロックサイズ{  
  58. パニック("暗号文が短すぎます")  
  59. }  
  60. iv : =暗号化[:aes.BlockSize]  
  61. 暗号化暗号化= 暗号化[aes.BlockSize:]  
  62. ストリーム: = cipher .NewCFBDecrypter(block, iv)  
  63. stream.XORKeyStream(暗号化、暗号化)  
  64. 暗号化して返す 
  65. }  
  66. 関数main() {  
  67. ソース: = "hello world"    
  68. fmt.Println("元の文字:",ソース)  
  69. key: = "ABCDEFGHIJKLMNO1" //16 ビット 
  70. encryptCode : = AesEncryptCFB ([]byte(ソース),[]byte(キー))  
  71. fmt.Println("暗号文:",hex.EncodeToString(encryptCode))  
  72. 復号コード: = AesDecryptCFB (暗号化コード、[]バイト(キー))  
  73. fmt.Println("復号化:", string(decryptCode))  
  74. }

OFBモード

  1. パッケージメイン 
  2. 輸入 (  
  3. 「バイト」  
  4. 「暗号/AES」  
  5. 「暗号」  
  6. 「暗号/ランド」  
  7. 「エンコーディング/16進数」  
  8. 「fmt」  
  9. 「イオ」  
  10.  
  11. func aesEncryptOFB( データ[]バイト, キー[]バイト) ([]バイト, エラー) {  
  12. データ= PKCS7Padding (データ、aes.BlockSize)  
  13. ブロック、_ : = aes .NewCipher([]byte(key))  
  14. 出力: = make ([]byte, aes.BlockSize + len(data))  
  15. iv : =出力[:aes.BlockSize]  
  16. _ の場合、 err : = io .ReadFull(rand.Reader, iv); err != nil {  
  17. nil、エラーを返す 
  18. }  
  19. ストリーム: = cipher .NewOFB(ブロック、iv)  
  20. stream.XORKeyStream(out[aes.BlockSize:], データ)  
  21. 戻り値: 0  
  22. }  
  23. func aesDecryptOFB( データ[]バイト, キー[]バイト) ([]バイト, エラー) {  
  24. ブロック、_ : = aes .NewCipher([]byte(key))  
  25. iv : =データ[:aes.BlockSize]  
  26. データデータ= データ[aes.BlockSize:]  
  27. len(データ) % aes.BlockSize != 0 の場合 {  
  28. nil を返します。fmt.Errorf("データはブロック サイズの倍数ではありません")  
  29. }  
  30. 出力: = make ([]byte, len(data))  
  31. モード: =暗号.NewOFB(ブロック、iv)  
  32. mode.XORKeyStream(出力、データ)  
  33. 出力= PKCS7UnPadding (出力)  
  34. 戻り値: 0  
  35. }  
  36. //補足コード 
  37. //AESで暗号化されたデータブロックの長さは128ビット(バイト[16])である必要があり、キーの長さは128ビット(バイト[16])、192ビット(バイト[24])、256ビット(バイト[32])のいずれかになります。  
  38. PKCS7Padding関数(暗号文[]byte, ブロックサイズint) []byte {  
  39. パディング: =ブロックサイズ- 長さ(暗号文)%ブロックサイズ 
  40. padtext : = bytes .Repeat([]byte{byte(padding)}, padding)  
  41. append(ciphertext, padtext...) を返します 
  42. }  
  43. //デコード 
  44. PKCS7UnPadding関数(origData[]byte)[]byte{  
  45. 長さ: = len (origData)  
  46. アンパディング: = int (origData[length-1])  
  47. origData[:(長さ - パディングなし)] を返す 
  48. }  
  49. 関数main() {  
  50. ソース: = "hello world"    
  51. fmt.Println("元の文字:",ソース)  
  52. key: = "1111111111111111" //16 ビットまたは 32 ビットのどちらも許容されます 
  53. encryptCode, _: = aesEncryptOFB ([]byte(ソース),[]byte(キー))  
  54. fmt.Println("暗号文:",hex.EncodeToString(encryptCode))  
  55. 復号コード、 _: = aesDecryptOFB (暗号化コード、[]byte(キー))  
  56. fmt.Println("復号化:", string(decryptCode))  
  57. }

RSA暗号化

まずopensslを使って公開鍵と秘密鍵を生成します

  1. パッケージメイン
  2. 輸入 (  
  3. 「暗号/ランド」
  4. 「暗号/RSA」  
  5. 「暗号/x509」  
  6. 「エンコーディング/base64」
  7. 「エンコーディング/pem」  
  8. 「エラー」  
  9. 「fmt」  
  10. // 秘密鍵を生成する 
  11. //openssl genrsa -out rsa_private_key.pem 1024  
  12. varプライベートキー= []byte(`  
  13. -----RSA 秘密鍵の開始-----  
  14. MIICWwIBAAKBgQDcGsUIIAINHfRTdMmgGwLrjzfMNSrtgIf4EGsNaYwmC1GjF/bM  
  15. h0Mcm10oLhNrKNYCTTQVGGIxuc5heKd1gOzb7bdTnCDPPZ7oV7p1B9Pud+6zパコ 
  16. qDz2M24vHFWYY2FbIIJh8fHhKcfXNXOLovdVBE7Zy682X1+R1lRK8D+vmQIDAQAB  
  17. アオガエワズvz1HZExca5k/hpbeqV+0+VtobMgwMs96+U53BpO/VRzl8Cu3CpNyb7HY  
  18. 64L9YQ+J5QgpPhqkgIO0dMu/0RIXsmhvr2gcxmKObcqT3JQ6S4rjHTln49I2sYTz  
  19. 7JEH4TcplKjSjHyq5MhHfA+CV2/AB2BO6G8limu7SheXuvECQQDwOpZrZDeTOOBk
  20. z1vercawd+J9ll/FZYttnrWYTI1sSF1sNfZ7dUXPyYPQFZ0LQ1bhZGmWBZ6a6wd9  
  21. R+PKlmJvAkEA6o32c/WEXxW2zeh18sOO4wqUiBYq3L3hFObhcsUAY8jfykQefW8q
  22. yPuuL02jLIajFWd0itjvIrzWnVmoUuXydwJAXGLrvllIVkIlah+lATprkypH3Gyc
  23. YFnxCTNkOzIVoXMjGp6WMFylgIfLPZdSUiaPnxby1FNM7987fh7Lp/m12QJAK9iL
  24. 2JNtwkSR3p305oOuAz0oFORn8MnB+KFMRaMT9pNHWk0vke0lB1sc7ZTKyvkEJW0o
  25. 翻訳:  
  26. 翻訳:  
  27. -----RSA秘密鍵終了-----  
  28. `)  
  29. // 公開鍵: 秘密鍵に基づいて生成 
  30. //openssl rsa -in rsa_private_key.pem -pubout -out rsa_public_key.pem
  31. var公開キー= [] バイト(`  
  32. -----公開鍵の開始-----  
  33. MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDcGsUIIAINHfRTdMmgGwLrjzfM  
  34. NSrtgIf4EGsNaYwmC1GjF/bMh0Mcm10oLhNrKNYCTTQVGGIxuc5heKd1gOzb7bdT  
  35. nCDPPZ7oV7p1B9Pud+6zPacoqDz2M24vHFWYY2FbIIJh8fHhKcfXNXOLovdVBE7Z
  36. y682X1+R1lRK8D+vmQIDAQAB  
  37. -----公開鍵終了-----  
  38. `)  
  39. // 暗号化 
  40. func RsaEncrypt(origData []byte) ([]byte, error) {  
  41. //pem形式の公開鍵を復号化する 
  42. ブロック、_ : = pem .Decode(publicKey)  
  43. ブロック== nil {  
  44. nil を返します。errors.New("公開鍵エラー")  
  45. }  
  46. // 公開鍵を解析する
  47. pubInterface、エラー: = x509.ParsePKIXPublicKey (block.Bytes)  
  48. err != nil の場合 {  
  49. nil、エラーを返す 
  50. }  
  51. // 型アサーション 
  52. pub : = pubInterface .(*rsa.PublicKey)  
  53. //暗号化 
  54. rsa.EncryptPKCS1v15(rand.Reader, pub, origData) を返します。  
  55. }  
  56. // 復号化 
  57. func RsaDecrypt(暗号文 []byte) ([]byte, error) {  
  58. //復号化 
  59. ブロック、_ : = pem .Decode(privateKey)
  60. ブロック== nil {  
  61. nil を返します。errors.New("秘密鍵エラー!")  
  62. }
  63. //PKCS1形式の秘密鍵を解析する 
  64. priv、err : = x509.ParsePKCS1PrivateKey (ブロック.バイト)  
  65. err != nil の場合 {
  66. nil、エラーを返す 
  67. }  
  68. // 復号化
  69. rsa.DecryptPKCS1v15(rand.Reader, priv, ciphertext) を返します。  
  70. }
  71. 関数main() {  
  72. データ、_ : = RsaEncrypt ([]byte("hello world"))  
  73. fmt.Println(base64.StdEncoding.EncodeToString(データ))
  74. origData, _ : = RsaDecrypt (データ)  
  75. fmt.Println(文字列(元のデータ))  
  76. }

<<:  マイクロソフト、AIの高得点宿題を配布、オンラインでコピーを求める

>>:  技術専門家によると、これらの15の仕事は決してAIに置き換えられないだろう

ブログ    
ブログ    
ブログ    

推薦する

アリババのナレッジグラフが初めて公開: 1日あたり数千万のブロックデータ、数十億の完全インテリジェント監査

アリババのナレッジグラフの助けにより、アリババの電子商取引プラットフォームの管理と制御は、以前の「巡...

チューリング賞受賞者のベンジオが新論文を発表、Redditがクラッシュ: アイデアがクラッシュ

[[403771]]機械学習における重要な研究はモデルの一般化を改善することであり、モデルをトレーニ...

...

Java で一般的に使用されているいくつかの暗号化アルゴリズムは、最も強力なハッカーでも解読できません。

シンプルな Java 暗号化アルゴリズムは次のとおりです。厳密に言えば、BASE は暗号化アルゴリズ...

ついに、データ、情報、アルゴリズム、統計、確率、データマイニングをわかりやすく説明した人がいました。

[[328804]] 【ガイド】AI時代では、データ、情報、アルゴリズム、統計、確率、データマイニ...

...

...

科学者たちは、脳波を3%という低いエラー率で直接テキストに変換する「心を読む」方法を開発した。

この記事はLeiphone.comから転載したものです。転載する場合は、Leiphone.com公式...

Objective-C 実装と主要なソートアルゴリズムのグラフィカルなデモンストレーション比較

[[176714]] Objective-C を使用していくつかの基本的なソート アルゴリズムを実装...

テンセントの馬化騰、センスタイムの唐暁ら6人の大物が人工知能の過去、現在、未来を深く解釈する

[[203162]]テクノロジー、特に今人気の人工知能は、生活、ビジネス、学術などにどれほどの影響を...

顔認識技術の原理と応用展望の分析

顔認識技術は人間の顔の特徴に基づいています。まず、入力された顔画像またはビデオ ストリームに顔がある...

スマートホームシステム設計の5つの原則

スマートホームコントロールの開発の鍵は、設計コンセプトとオペレーターの考え方にあります。市場のターゲ...

...

Gizwits Cloud はスマートホームが機械にユーザーをよりよく理解するのを助けます

[51CTO.com からのオリジナル記事] 2016年、国内投資家のVRへの熱意はまだ薄れていなか...

DockerとFlaskをベースにしたディープラーニングモデルのデプロイメント!

モデルの展開は、ディープラーニング アルゴリズムの実装において常に重要な部分です。ディープラーニング...