Симметричное шифрование файлов. Golang-Python
Ниже пример шифрования/дешифрирования данных аналогично этому но не в консоли, а на двух языках.
Шифрование Go
package main
import (
"crypto/aes"
"crypto/cipher"
"crypto/sha256"
"fmt"
)
func genKey(password string) []byte {
h := sha256.New()
h.Write([]byte(password))
return h.Sum(nil)
}
func genIV(password string) []byte {
iv := make([]byte, 16)
for i := 0; i < 16 && i < len(password); i++ {
iv[i] = password[i]
}
return iv
}
func main() {
pass := "idkfa"
hash := genKey(pass)
iv := genIV(pass)
block, err := aes.NewCipher(hash)
if err != nil {
panic(err)
}
a, err := cipher.NewGCMWithNonceSize(block, 16)
if err != nil {
panic(err)
}
ctxt := a.Seal(nil, iv, []byte("iddqd"), nil)
result := append(iv, ctxt...)
fmt.Printf("Key: %x\n", hash)
fmt.Printf("iv: %x\n", iv)
fmt.Printf("Tag: %x\n", ctxt[len(ctxt)-16:])
fmt.Printf("Enc: %x", result)
}
Тут в результирующий закодированный блок попадает iv, и tag подписи. То есть при расшифровке лучше помнить, что первые 16 байт (в этом примере) являются IV.
Расшифровка на python
from hashlib import sha256
from Crypto.Cipher import AES
# Данные из Go-программы
password = "idkfa"
ctxt_hex = "69646b66610000000000000000000000dcffaf694b09265031430505cff7af496c36a0998d"
# Получаем ключ
key = sha256(password.encode()).digest()
# Парсим шифротекст: первые 16 байт — это IV
ctxt = bytes.fromhex(ctxt_hex)
iv = ctxt[:16]
ciphertext_and_tag = ctxt[16:]
# Последние 16 байт — это тег (tag), остальное — ciphertext
ciphertext = ciphertext_and_tag[:-16]
tag = ciphertext_and_tag[-16:]
print(tag)
# Дешифрование
cipher = AES.new(key, AES.MODE_GCM, nonce=iv, mac_len=16)
plaintext = cipher.decrypt_and_verify(ciphertext, tag)
print("Расшифрованный текст:", plaintext.decode())
Тут надо в переменную ctxt_hex
сложить результат работы первой программы. Необходима библиотека pycryptodome
.