AES加密和解密在Golang和Flutter之间的实现

huangapple go评论105阅读模式
英文:

AES Encryption and Decryption between Golang and Flutter

问题

我有一个能够对给定数据进行AES加密并提供服务的Golang代码。以下是代码。

crypt.go

func encrypt(key []byte, text string) string {

	plaintext := []byte(text)

	block, err := aes.NewCipher(key)
	if err != nil {
		panic(err)
	}

	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.URLEncoding.EncodeToString(ciphertext)
}

func decrypt(key []byte, cryptoText string) string {
	ciphertext, _ := base64.URLEncoding.DecodeString(cryptoText)

	block, err := aes.NewCipher(key)
	if err != nil {
		panic(err)
	}

	if len(ciphertext) < aes.BlockSize {
		panic("ciphertext too short")
	}
	iv := ciphertext[:aes.BlockSize]
	ciphertext = ciphertext[aes.BlockSize:]

	stream := cipher.NewCFBDecrypter(block, iv)
	stream.XORKeyStream(ciphertext, ciphertext)

	return string(ciphertext)
}

我需要在Flutter中处理相同的解密和加密。我尝试使用flutter encrypt包的以下代码。

crypt.dart

import 'package:encrypt/encrypt.dart';
String encryption(String plainText) {
     
     final key = Key.fromBase64(ENCRYPTION_KEY);
     final iv = IV.fromBase64(ENCRYPTION_IV);

     final encrypter = Encrypter(AES(key, mode: AESMode.cfb64, padding: null));
     final encrypted = encrypter.encrypt(plainText, iv: iv);

 return encrypted.base64;   
}

String decryption(String plainText) {

   final key = Key.fromBase64(ENCRYPTION_KEY);
   final iv = IV.fromBase64(ENCRYPTION_IV);

   final encrypter = Encrypter(AES(key, mode: AESMode.cfb64, padding: null));
   final decrypted = encrypter.decrypt(Encrypted.from64(plainText), iv: iv);

  return decrypted;   
 }

但是我遇到了错误,代码无法正常工作。我是否漏掉了什么?在Flutter端如何实现这个功能?

提前感谢。

英文:

I have a golang code which can do AES encryption on the given data and serves it. Below is the code.

crypt.go

func encrypt(key []byte, text string) string {

	plaintext := []byte(text)

	block, err := aes.NewCipher(key)
	if err != nil {
		panic(err)
	}

	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.URLEncoding.EncodeToString(ciphertext)
}

func decrypt(key []byte, cryptoText string) string {
	ciphertext, _ := base64.URLEncoding.DecodeString(cryptoText)

	block, err := aes.NewCipher(key)
	if err != nil {
		panic(err)
	}

	if len(ciphertext) &lt; aes.BlockSize {
		panic(&quot;ciphertext too short&quot;)
	}
	iv := ciphertext[:aes.BlockSize]
	ciphertext = ciphertext[aes.BlockSize:]

	stream := cipher.NewCFBDecrypter(block, iv)
	stream.XORKeyStream(ciphertext, ciphertext)

	return string(ciphertext)
}

I need to handle the same decryption and encryption in Flutter. I tried the below code using flutter encrypt package.

crypt.dart

import &#39;package:encrypt/encrypt.dart&#39;;
String encryption(String plainText) {
     
     final key = Key.fromBase64(ENCRYPTION_KEY);
     final iv = IV.fromBase64(ENCRYPTION_IV);

     final encrypter = Encrypter(AES(key, mode: AESMode.cfb64, padding: null));
     final encrypted = encrypter.encrypt(plainText, iv: iv);

 return encrypted.base64;   
}

String decryption(String plainText) {

   final key = Key.fromBase64(ENCRYPTION_KEY);
   final iv = IV.fromBase64(ENCRYPTION_IV);

   final encrypter = Encrypter(AES(key, mode: AESMode.cfb64, padding: null));
   final decrypted = encrypter.decrypt(Encrypted.from64(plainText), iv: iv);

  return decrypted;   
 }

But I'm getting error and is not working. Am I missing something?
How this can be achieved in flutter end.

Thanks in advance

答案1

得分: 1

乍一看,似乎你的iv(初始化向量)不匹配。在Go中进行加密时,你会随机生成它,并将其“放置”在加密文本的前面,这是可以的;而在Go中进行解密时,你会从那里获取它。

在Dart中(虽然我不熟悉该语言),似乎你从ENCRYPTION_IV中获取一个静态的iv。这个iv与从Go中随机生成的iv不匹配。

可以将iv想象成一种密码。它解释了如何处理加密密钥。通常它不是秘密的,但应该是随机的。因此,可以使用适当的随机生成器生成它,并告诉接收加密文本的人。一种常见的方法是将其放在文本的前面-因为在AES中,它的大小固定为aes.BlockSize(16字节),所以很明显iv在哪里结束,真正的加密文本从哪里开始。

因此,在Dart中,你应该从Go加密的密文中读取前16个字节以获取iv。顺便说一下,我建议在Dart的加密方法中也使用随机的iv。

英文:

At a first glance it seems like your iv (initialization vectors) don't match. When encrypting in Go, you generate it randomly and "place" it in front of the encrypted text, which is fine, and when decrypting in Go, you take it from there.

In Dart (I'm not used to that language though) it seems as you take a static iv from ENCRYPTION_IV. That one won't match a randomly generated one from Go.

Imagine the iv being some kind of clef. It explains how to process the encrypted key. Normally it's not secret, but should be random. So it's fine to generate it with an appropriate randomizer and tell the receiver of the encrypted text about it. A common way is to put it in the front of it - since it's size is fixed in AES to aes.BlockSize (16 bytes), it's clear where the iv ends and the real encrypted text starts.

So, in Dart you should read the first 16 bytes to get the iv from the ciphertext from Go encryption. And while you're at it, I'ld recommend to use a random iv in the Dart encryption method, too.

huangapple
  • 本文由 发表于 2022年11月4日 14:47:07
  • 转载请务必保留本文链接:https://go.coder-hub.com/74313138.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定