[[343693]] 序文 実際の開発では、暗号化と復号化が広く使用されています。一般的に使用される暗号化と復号化は、「対称」、「非対称」、「デジタル署名」に分けられます。 対称: 対称暗号化 (秘密鍵暗号化とも呼ばれる) は、暗号化と復号化に同じ鍵を使用する暗号化アルゴリズムを指します。具体的なアルゴリズムには、DES アルゴリズム、3DES アルゴリズム、TDEA アルゴリズム、Blowfish アルゴリズム、RC5 アルゴリズム、IDEA アルゴリズムなどがあります。 非対称暗号化 (公開鍵暗号化): 暗号化と復号化に異なる鍵を使用する暗号化アルゴリズムを指します。公開鍵暗号化とも呼ばれます。具体的なアルゴリズムとしては、RSA、Elgamal、バックパックアルゴリズム、Rabin、DH、ECC(楕円曲線暗号化アルゴリズム)などがあります。 デジタル署名: デジタル署名は、非対称キー暗号化技術とデジタル要約技術の応用です。主なアルゴリズムには、md5、hmac、sha1 などがあります。 以下では、golang 言語の主な暗号化および復号化アルゴリズムの実装を紹介します。 MD5 MD5 メッセージ ダイジェスト アルゴリズムは、情報伝送の整合性と一貫性を確保するために 128 ビット (16 進数、32 文字) のハッシュ値を生成できる、広く使用されている暗号化ハッシュ関数です。 - GetMd5String関数(文字列)文字列{
- h : = md5.New ()です。
- h.Write([]バイト)
- hex.EncodeToString(h.Sum(nil)) を返す
- }
hmac HMAC は、ハッシュベースのメッセージ認証コードの略です。 ハッシュ計算プロセス中にキーを計算プロセスに組み込むために標準アルゴリズムを使用します。 当社のカスタム ソルト アルゴリズムとは異なり、Hmac アルゴリズムは、MD5 または SHA-1 を問わず、すべてのハッシュ アルゴリズムに共通です。独自のソルト アルゴリズムの代わりに Hmac を使用すると、プログラム アルゴリズムをより標準化し、より安全にすることができます。 例 - //キーは任意に設定可能で、データを暗号化するデータ
- func Hmac(キー, データ文字列) 文字列 {
- hash: = hmac .New(md5.New, []byte(key)) // 対応するmd5ハッシュ暗号化アルゴリズムを作成する
- ハッシュ.Write([]byte(データ))
- hex.EncodeToString(hash.Sum([]byte(""))) を返します
- }
- func HmacSha256(キー、データ文字列) 文字列 {
- hash: = hmac .New(sha256.New, []byte(key)) //対応するsha256ハッシュ暗号化アルゴリズムを作成する
- ハッシュ.Write([]byte(データ))
- hex.EncodeToString(hash.Sum([]byte(""))) を返します
- }
シャ1 SHA-1 は、メッセージ ダイジェストと呼ばれる 160 ビット (20 バイト) のハッシュ値を生成します。これは通常、40 桁の 16 進数として表されます。 - func Sha1(データ文字列) 文字列 {
- sha1 : = sha1.New () です。
- sha1.Write([]バイト(データ))
- hex.EncodeToString(sha1.Sum([]byte(""))) を返します。
- }
エーエス 暗号化における 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 モードをサポートしていません。 - パッケージメイン
- 輸入 (
- 「暗号/AES」
- 「fmt」
- )
- func AESEncrypt(src []byte, key []byte) (暗号化された[]byte) {
- 暗号、_ : = aes .NewCipher(generateKey(key))
- 長さ: = (len(src) + aes.BlockSize) / aes.BlockSize
- プレーン: = make ([]byte, length*aes.BlockSize)
- コピー(プレーン, src)
- pad : =バイト(len(plain) - len(src))
- i : = len (src); i < len (プレーン); i++ {
- プレーン[i] = パッド
- }
- 暗号化= make ([]byte, len(plain))
- // グループで暗号化
- bs, be : = 0 、cipher.BlockSize(); bs < = len(src); bs, be = bs +cipher.BlockSize()、be+cipher.BlockSize() {
- cipher.Encrypt(暗号化[bs:be]、プレーン[bs:be])
- }
- 暗号化して返す
- }
- func AESDecrypt(暗号化された[]バイト、キー[]バイト) (復号化された[]バイト) {
- 暗号、_ : = aes .NewCipher(generateKey(key))
- 復号化= make ([]byte, len(暗号化))
- //
- bsの場合、be : = 0 、cipher.BlockSize(); bs < len (暗号化済み); bs, be = bs + cipher.BlockSize(), be + cipher.BlockSize() {
- cipher.Decrypt(復号化[bs:be]、暗号化[bs:be])
- }
- トリム: = 0
- len(復号化) > 0 の場合 {
- トリム= len (復号化) - int(復号化[len(復号化)-1])
- }
- 復号化された[:trim]を返す
- }
- 関数generateKey(key []byte) (genKey []byte) {
- genKey = make ([]バイト、16)
- コピー(genKey、キー)
- i : = 16 の場合、i < len (キー);
- j : = 0の場合; j < 16 && 私< len (キー); j, i = j +1, i+1 {
- genKey[j] ^= キー[i]
- }
- }
- genKeyを返す
- }
- 関数main() {
- ソース: = "hello world"
- fmt.Println("元の文字:",ソース)
- //16バイトのキー
- キー: = "1443flfsaWfdas"
- encryptCode: = AESEncrypt ([]byte(ソース),[]byte(キー))
- fmt.Println("暗号文:", string(encryptCode))
- decryptCode: = AESDecrypt (encryptCode, []byte(key))
- fmt.Println("復号化:", string(decryptCode))
- }
CBCモード - パッケージメイン
- 輸入(
- 「バイト」
- 「暗号/AES」
- 「fmt」
- 「暗号」
- 「エンコーディング/base64」
- )
- 関数main() {
- orig : = "こんにちは世界"
- キー: = "0123456789012345"
- fmt.Println("元のテキスト:", orig)
- encryptCode : = AesEncrypt (orig, key)
- fmt.Println("暗号文: ", 暗号化コード)
- 復号コード: = AesDecrypt (暗号化コード、キー)
- fmt.Println("復号結果:", decryptCode)
- }
- func AesEncrypt(元の文字列、キー文字列) 文字列 {
- // バイト配列に変換
- origData : = []byte(orig)
- k : = []バイト(キー)
- // グループキー
- // NewCipher この関数は入力kの長さを16、24、または32に制限します
- ブロック、_ : = aes .NewCipher(k)
- // キーブロックの長さを取得する
- ブロックサイズ: =ブロック.BlockSize()
- //完全なコード
- origData = PKCS7Padding (origData, ブロックサイズ)
- // 暗号化モード
- blockMode : = cipher .NewCBCEncrypter(block, k[:blockSize])
- // 配列を作成する
- cryted : = make ([]byte, len(origData))
- // 暗号化
- blockMode.CryptBlocks(暗号化済み、元のデータ)
- base64.StdEncoding.EncodeToString(cryted) を返します。
- }
- func AesDecrypt(暗号化された文字列、キー文字列) 文字列 {
- // バイト配列に変換
- crytedByte、_ : = base64.StdEncoding.DecodeString (cryted)
- k : = []バイト(キー)
- // グループキー
- ブロック、_ : = aes .NewCipher(k)
- // キーブロックの長さを取得する
- ブロックサイズ: =ブロック.BlockSize()
- // 暗号化モード
- blockMode : = cipher .NewCBCDecrypter(block, k[:blockSize])
- // 配列を作成する
- orig : = make ([]byte, len(crytedByte))
- // 復号化
- blockMode.CryptBlocks(orig, 暗号化バイト)
- // コードを完成させる
- オリジナル= PKCS7UnPadding (オリジナル)
- 文字列を返す(orig)
- }
- //補足コード
- //AESで暗号化されたデータブロックの長さは128ビット(バイト[16])である必要があり、キーの長さは128ビット(バイト[16])、192ビット(バイト[24])、256ビット(バイト[32])のいずれかになります。
- PKCS7Padding関数(暗号文[]byte, ブロックサイズint) []byte {
- パディング: =ブロックサイズ- 長さ(暗号文)%ブロックサイズ
- padtext : = bytes .Repeat([]byte{byte(padding)}, padding)
- append(ciphertext, padtext...) を返します
- }
- //デコード
- PKCS7UnPadding関数(origData[]byte)[]byte{
- 長さ: = len (origData)
- アンパディング: = int (origData[length-1])
- origData[:(長さ - パディングなし)] を返す
- }
CRTモード - パッケージメイン
- 輸入 (
- 「バイト」
- 「暗号/AES」
- 「暗号」
- 「fmt」
- )
- //暗号化
- func aesCtrCrypt(プレーンテキスト []byte, キー []byte) ([]byte, エラー) {
- //1. cipher.Blockインターフェースを作成する
- ブロック、エラー: = aes .NewCipher(キー)
- err != nil の場合 {
- nil、エラーを返す
- }
- //2. crypto/cipher パッケージでグループ化パターンを作成する
- iv : =バイト.Repeat([]byte("1"), block.BlockSize())
- ストリーム: = cipher .NewCTR(ブロック、iv)
- //3. 暗号化
- dst : = make ([]byte, len(プレーンテキスト))
- stream.XORKeyStream(dst, プレーンテキスト)
- dst、nil を返す
- }
- 関数main() {
- ソース: = "hello world"
- fmt.Println("元の文字:",ソース)
- キー: = "1443flfsaWfdasds"
- encryptCode, _: = aesCtrCrypt ([]byte(ソース),[]byte(キー))
- fmt.Println("暗号文:", string(encryptCode))
- 復号コード、 _: = aesCtrCrypt (暗号化コード、[]byte (キー))
- fmt.Println("復号化:", string(decryptCode))
- }
- CFBモード
- パッケージメイン
- 輸入 (
- 「暗号/AES」
- 「暗号」
- 「暗号/ランド」
- 「エンコーディング/16進数」
- 「fmt」
- 「イオ」
- )
- func AesEncryptCFB(origData []byte, key []byte) (暗号化された []byte) {
- ブロック、エラー: = aes .NewCipher(キー)
- err != nil の場合 {
- //パニック(エラー)
- }
- 暗号化= make ([]byte, aes.BlockSize+len(origData))
- iv : =暗号化[:aes.BlockSize]
- _ の場合、 err : = io .ReadFull(rand.Reader, iv); err != nil {
- //パニック(エラー)
- }
- ストリーム: = cipher .NewCFBEncrypter(block, iv)
- stream.XORKeyStream(暗号化[aes.BlockSize:], 元のデータ)
- 暗号化して返す
- }
- func AesDecryptCFB(暗号化された[]バイト、キー[]バイト) (復号化された[]バイト) {
- ブロック、_ : = aes .NewCipher(キー)
- len(暗号化) < aes.ブロックサイズ{
- パニック("暗号文が短すぎます")
- }
- iv : =暗号化[:aes.BlockSize]
- 暗号化暗号化= 暗号化[aes.BlockSize:]
- ストリーム: = cipher .NewCFBDecrypter(block, iv)
- stream.XORKeyStream(暗号化、暗号化)
- 暗号化して返す
- }
- 関数main() {
- ソース: = "hello world"
- fmt.Println("元の文字:",ソース)
- key: = "ABCDEFGHIJKLMNO1" //16 ビット
- encryptCode : = AesEncryptCFB ([]byte(ソース),[]byte(キー))
- fmt.Println("暗号文:",hex.EncodeToString(encryptCode))
- 復号コード: = AesDecryptCFB (暗号化コード、[]バイト(キー))
- fmt.Println("復号化:", string(decryptCode))
- }
OFBモード - パッケージメイン
- 輸入 (
- 「バイト」
- 「暗号/AES」
- 「暗号」
- 「暗号/ランド」
- 「エンコーディング/16進数」
- 「fmt」
- 「イオ」
- )
- func aesEncryptOFB( データ[]バイト, キー[]バイト) ([]バイト, エラー) {
- データ= PKCS7Padding (データ、aes.BlockSize)
- ブロック、_ : = aes .NewCipher([]byte(key))
- 出力: = make ([]byte, aes.BlockSize + len(data))
- iv : =出力[:aes.BlockSize]
- _ の場合、 err : = io .ReadFull(rand.Reader, iv); err != nil {
- nil、エラーを返す
- }
- ストリーム: = cipher .NewOFB(ブロック、iv)
- stream.XORKeyStream(out[aes.BlockSize:], データ)
- 戻り値: 0
- }
- func aesDecryptOFB( データ[]バイト, キー[]バイト) ([]バイト, エラー) {
- ブロック、_ : = aes .NewCipher([]byte(key))
- iv : =データ[:aes.BlockSize]
- データデータ= データ[aes.BlockSize:]
- len(データ) % aes.BlockSize != 0 の場合 {
- nil を返します。fmt.Errorf("データはブロック サイズの倍数ではありません")
- }
- 出力: = make ([]byte, len(data))
- モード: =暗号.NewOFB(ブロック、iv)
- mode.XORKeyStream(出力、データ)
- 出力= PKCS7UnPadding (出力)
- 戻り値: 0
- }
- //補足コード
- //AESで暗号化されたデータブロックの長さは128ビット(バイト[16])である必要があり、キーの長さは128ビット(バイト[16])、192ビット(バイト[24])、256ビット(バイト[32])のいずれかになります。
- PKCS7Padding関数(暗号文[]byte, ブロックサイズint) []byte {
- パディング: =ブロックサイズ- 長さ(暗号文)%ブロックサイズ
- padtext : = bytes .Repeat([]byte{byte(padding)}, padding)
- append(ciphertext, padtext...) を返します
- }
- //デコード
- PKCS7UnPadding関数(origData[]byte)[]byte{
- 長さ: = len (origData)
- アンパディング: = int (origData[length-1])
- origData[:(長さ - パディングなし)] を返す
- }
- 関数main() {
- ソース: = "hello world"
- fmt.Println("元の文字:",ソース)
- key: = "1111111111111111" //16 ビットまたは 32 ビットのどちらも許容されます
- encryptCode, _: = aesEncryptOFB ([]byte(ソース),[]byte(キー))
- fmt.Println("暗号文:",hex.EncodeToString(encryptCode))
- 復号コード、 _: = aesDecryptOFB (暗号化コード、[]byte(キー))
- fmt.Println("復号化:", string(decryptCode))
- }
RSA暗号化 まずopensslを使って公開鍵と秘密鍵を生成します - パッケージメイン
- 輸入 (
- 「暗号/ランド」
- 「暗号/RSA」
- 「暗号/x509」
- 「エンコーディング/base64」
- 「エンコーディング/pem」
- 「エラー」
- 「fmt」
- )
- // 秘密鍵を生成する
- //openssl genrsa -out rsa_private_key.pem 1024
- varプライベートキー= []byte(`
- -----RSA 秘密鍵の開始-----
- MIICWwIBAAKBgQDcGsUIIAINHfRTdMmgGwLrjzfMNSrtgIf4EGsNaYwmC1GjF/bM
- h0Mcm10oLhNrKNYCTTQVGGIxuc5heKd1gOzb7bdTnCDPPZ7oV7p1B9Pud+6zパコ
- qDz2M24vHFWYY2FbIIJh8fHhKcfXNXOLovdVBE7Zy682X1+R1lRK8D+vmQIDAQAB
- アオガエワズvz1HZExca5k/hpbeqV+0+VtobMgwMs96+U53BpO/VRzl8Cu3CpNyb7HY
- 64L9YQ+J5QgpPhqkgIO0dMu/0RIXsmhvr2gcxmKObcqT3JQ6S4rjHTln49I2sYTz
- 7JEH4TcplKjSjHyq5MhHfA+CV2/AB2BO6G8limu7SheXuvECQQDwOpZrZDeTOOBk
- z1vercawd+J9ll/FZYttnrWYTI1sSF1sNfZ7dUXPyYPQFZ0LQ1bhZGmWBZ6a6wd9
- R+PKlmJvAkEA6o32c/WEXxW2zeh18sOO4wqUiBYq3L3hFObhcsUAY8jfykQefW8q
- yPuuL02jLIajFWd0itjvIrzWnVmoUuXydwJAXGLrvllIVkIlah+lATprkypH3Gyc
- YFnxCTNkOzIVoXMjGp6WMFylgIfLPZdSUiaPnxby1FNM7987fh7Lp/m12QJAK9iL
- 2JNtwkSR3p305oOuAz0oFORn8MnB+KFMRaMT9pNHWk0vke0lB1sc7ZTKyvkEJW0o
- 翻訳:
- 翻訳:
- -----RSA秘密鍵終了-----
- `)
- // 公開鍵: 秘密鍵に基づいて生成
- //openssl rsa -in rsa_private_key.pem -pubout -out rsa_public_key.pem
- var公開キー= [] バイト(`
- -----公開鍵の開始-----
- MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDcGsUIIAINHfRTdMmgGwLrjzfM
- NSrtgIf4EGsNaYwmC1GjF/bMh0Mcm10oLhNrKNYCTTQVGGIxuc5heKd1gOzb7bdT
- nCDPPZ7oV7p1B9Pud+6zPacoqDz2M24vHFWYY2FbIIJh8fHhKcfXNXOLovdVBE7Z
- y682X1+R1lRK8D+vmQIDAQAB
- -----公開鍵終了-----
- `)
- // 暗号化
- func RsaEncrypt(origData []byte) ([]byte, error) {
- //pem形式の公開鍵を復号化する
- ブロック、_ : = pem .Decode(publicKey)
- ブロック== nil {
- nil を返します。errors.New("公開鍵エラー")
- }
- // 公開鍵を解析する
- pubInterface、エラー: = x509.ParsePKIXPublicKey (block.Bytes)
- err != nil の場合 {
- nil、エラーを返す
- }
- // 型アサーション
- pub : = pubInterface .(*rsa.PublicKey)
- //暗号化
- rsa.EncryptPKCS1v15(rand.Reader, pub, origData) を返します。
- }
- // 復号化
- func RsaDecrypt(暗号文 []byte) ([]byte, error) {
- //復号化
- ブロック、_ : = pem .Decode(privateKey)
- ブロック== nil {
- nil を返します。errors.New("秘密鍵エラー!")
- }
- //PKCS1形式の秘密鍵を解析する
- priv、err : = x509.ParsePKCS1PrivateKey (ブロック.バイト)
- err != nil の場合 {
- nil、エラーを返す
- }
- // 復号化
- rsa.DecryptPKCS1v15(rand.Reader, priv, ciphertext) を返します。
- }
- 関数main() {
- データ、_ : = RsaEncrypt ([]byte("hello world"))
- fmt.Println(base64.StdEncoding.EncodeToString(データ))
- origData, _ : = RsaDecrypt (データ)
- fmt.Println(文字列(元のデータ))
- }
|