Skip to content

Instantly share code, notes, and snippets.

@mrgcohen
Forked from willshiao/aes.go
Created July 25, 2019 12:21
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mrgcohen/81a847960013d1252b58666b0358b18a to your computer and use it in GitHub Desktop.
Save mrgcohen/81a847960013d1252b58666b0358b18a to your computer and use it in GitHub Desktop.
AES 256-CFB in Node.js, Go, and Python
package main
import (
"crypto/aes"
"crypto/cipher"
"crypto/rand"
"crypto/sha256"
"encoding/base64"
"fmt"
"io"
)
func keyEncrypt(keyStr string, cryptoText string) string {
keyBytes := sha256.Sum256([]byte(keyStr))
return encrypt(keyBytes[:], cryptoText)
}
// encrypt string to base64 crypto using AES
func encrypt(key []byte, text string) string {
plaintext := []byte(text)
block, err := aes.NewCipher(key)
if err != nil {
panic(err)
}
// The IV needs to be unique, but not secure. Therefore it's common to
// include it at the beginning of the ciphertext.
ciphertext := make([]byte, aes.BlockSize+len(plaintext))
iv := ciphertext[:aes.BlockSize]
if _, err := io.ReadFull(rand.Reader, iv); err != nil {
panic(err)
}
stream := cipher.NewCFBEncrypter(block, iv)
stream.XORKeyStream(ciphertext[aes.BlockSize:], plaintext)
return base64.StdEncoding.EncodeToString(ciphertext)
}
func keyDecrypt(keyStr string, cryptoText string) string {
keyBytes := sha256.Sum256([]byte(keyStr))
return decrypt(keyBytes[:], cryptoText)
}
// decrypt from base64 to decrypted string
func decrypt(key []byte, cryptoText string) string {
ciphertext, err := base64.StdEncoding.DecodeString(cryptoText)
if err != nil {
panic(err)
}
block, err := aes.NewCipher(key)
if err != nil {
panic(err)
}
// The IV needs to be unique, but not secure. Therefore it's common to
// include it at the beginning of the ciphertext.
if len(ciphertext) < aes.BlockSize {
panic("ciphertext too short")
}
iv := ciphertext[:aes.BlockSize]
ciphertext = ciphertext[aes.BlockSize:]
stream := cipher.NewCFBDecrypter(block, iv)
// XORKeyStream can work in-place if the two arguments are the same.
stream.XORKeyStream(ciphertext, ciphertext)
return fmt.Sprintf("%s", ciphertext)
}
func main() {
encrypted := "lIR3JIHpomC5Zm8sjy29D/xFcXUX0c/4vQ=="
fmt.Println(encrypted)
fmt.Println(keyDecrypt("SecretKey", encrypted))
}
'use strict';
const crypto = require('crypto');
const algorithm = 'aes-256-cfb';
function encryptText(keyStr, text) {
const hash = crypto.createHash('sha256');
hash.update(keyStr);
const keyBytes = hash.digest();
const iv = crypto.randomBytes(16);
const cipher = crypto.createCipheriv(algorithm, keyBytes, iv);
console.log('IV:', iv);
let enc = [iv, cipher.update(text, 'utf8')];
enc.push(cipher.final());
return Buffer.concat(enc).toString('base64');
}
function decryptText(keyStr, text) {
const hash = crypto.createHash('sha256');
hash.update(keyStr);
const keyBytes = hash.digest();
const contents = Buffer.from(text, 'base64');
const iv = contents.slice(0, 16);
const textBytes = contents.slice(16);
const decipher = crypto.createDecipheriv(algorithm, keyBytes, iv);
let res = decipher.update(textBytes, '', 'utf8');
res += decipher.final('utf8');
return res;
}
const encrypted = encryptText('SecretKey', 'It works!');
console.log('Encrypted: ', encrypted);
const decrypted = decryptText('SecretKey', encrypted);
console.log('Decrypted: ', decrypted);
import base64
import hashlib
from Crypto.Cipher import AES
from Crypto import Random
def encrypt(keyStr, text):
private_key = hashlib.sha256(keyStr.encode()).digest()
rem = len(text) % 16
padded = str.encode(text) + (b'\0' * (16 - rem)) if rem > 0 else text
iv = Random.new().read(AES.block_size)
cipher = AES.new(private_key, AES.MODE_CFB, iv, segment_size=128)
enc = cipher.encrypt(padded)[:len(text)]
return base64.b64encode(iv + enc).decode()
def decrypt(keyStr, text):
private_key = hashlib.sha256(keyStr.encode()).digest()
text = base64.b64decode(text)
iv, value = text[:16], text[16:]
rem = len(value) % 16
padded = value + (b'\0' * (16 - rem)) if rem > 0 else value
cipher = AES.new(private_key, AES.MODE_CFB, iv, segment_size=128)
return (cipher.decrypt(padded)[:len(value)]).decode()
def main():
encrypted = 'lIR3JIHpomC5Zm8sjy29D/xFcXUX0c/4vQ=='
print(encrypted)
print(decrypt('SecretKey', encrypted))
if __name__== '__main__':
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment