英文:
AES GCM decryption failed while decrypting data encrypted in flutter
问题
我正在尝试使用Golang中的内置crypto库解密数据,该数据是在Flutter/Dart中使用steel_crypt库进行加密的。
Golang的crypto库抛出的特定错误消息是:panic: cipher: message authentication failed
。
我在Android模拟器上运行Flutter应用程序 (本地主机是:10.0.2.2)。
> Golang版本:go1.17.6 linux/amd64 |
Flutter版本:Flutter 2.8.1 • channel stable |
Dart版本:Dart 2.15.1
Golang代码
package main
import (
"bufio"
"crypto"
"crypto/aes"
"crypto/cipher"
"crypto/rand"
"crypto/rsa"
"crypto/x509"
"encoding/base64"
"encoding/json"
"encoding/pem"
"errors"
"fmt"
"io"
"net"
)
func Encode(data []byte) string {
hb := base64.StdEncoding.EncodeToString([]byte(data))
return hb
}
// Decoding the base string to array of bytes
func Decode(data string) []byte {
hb, _ := base64.StdEncoding.DecodeString(data)
return hb
}
// Generating RSA private key
func GenerateRsaPrivateKey(size int) (*rsa.PrivateKey, error) {
privateKey, err := rsa.GenerateKey(rand.Reader, size)
if err != nil {
return nil, err
}
return privateKey, nil
}
// Generating RSA public key
func GenerateRsaPublicKey(privateKey *rsa.PrivateKey) rsa.PublicKey {
return privateKey.PublicKey
}
// This function can be use encrypt a plain text with rsa algorithm
func RsaEncrypt(publicKey rsa.PublicKey, data string) ([]byte, error) {
encryptedBytes, err := rsa.EncryptPKCS1v15(
rand.Reader,
&publicKey,
[]byte(data))
return encryptedBytes, err
// encryptedBytes, err := rsa.EncryptOAEP(
// sha256.New(),
// rand.Reader,
// &publicKey,
// []byte(data),
// nil)
// return encryptedBytes, err
}
// This function can be use decrypt a encrypted text with rsa algorithm
func RsaDecrypt(privateKey rsa.PrivateKey, data []byte) ([]byte, error) {
decryptedBytes, err := privateKey.Decrypt(
nil,
data,
&rsa.OAEPOptions{Hash: crypto.SHA256})
return decryptedBytes, err
}
// This fucntion is used to dump/serialize the rsa public key
func DumpKey(key *rsa.PublicKey) ([]byte, error) {
return x509.MarshalPKCS1PublicKey(key), nil
}
// This function is used to load the rsa public key
func LoadKey(byteKey []byte) (*rsa.PublicKey, error) {
key, err := x509.ParsePKCS1PublicKey(byteKey)
return key, err
}
// Generate fixed size byte array
func GenerateAesKey(size int) []byte {
token := make([]byte, size)
rand.Read(token)
return token
}
// This fucntion can be used for encrypting a plain text using AES-GCM algorithm
func AesEncryption(key []byte, data string) ([]byte, error) {
c, err := aes.NewCipher(key)
if err != nil {
return nil, err
}
gcm, err := cipher.NewGCM(c)
if err != nil {
return nil, err
}
nonce := make([]byte, gcm.NonceSize())
if _, err = io.ReadFull(rand.Reader, nonce); err != nil {
return nil, err
}
cipherText := gcm.Seal(nonce, nonce, []byte(data), nil)
return cipherText, nil
}
// This fucntion can be used for decrypting the ciphertext encrypted using AES-GCM algorithm
func AesDecryption(key []byte, cipherText []byte, nonce []byte) ([]byte, error) {
c, err := aes.NewCipher(key)
if err != nil {
fmt.Println("1")
return nil, err
}
gcm, err := cipher.NewGCM(c)
if err != nil {
fmt.Println("2")
return nil, err
}
noncesize := gcm.NonceSize()
if len(cipherText) < noncesize {
fmt.Println("3")
return nil, err
}
cipherText = cipherText[noncesize:]
// nonce, cipherText := cipherText[:noncesize], cipherText[noncesize:]
plainText, err := gcm.Open(nil, nonce, cipherText, nil)
if err != nil {
fmt.Println("4", err.Error())
return nil, err
}
return plainText, nil
}
func ParseRsaPublicKeyFromPemStr(pubPEM string) (*rsa.PublicKey, error) {
block, _ := pem.Decode([]byte(pubPEM))
if block == nil {
return nil, errors.New("failed to parse PEM block containing the key")
}
pub, err := x509.ParsePKIXPublicKey(block.Bytes)
if err != nil {
return nil, err
}
switch pub := pub.(type) {
case *rsa.PublicKey:
return pub, nil
default:
break // fall through
}
return nil, errors.New("Key type is not RSA")
}
type trans struct {
Key string `json:"key"`
}
type creden struct {
Data []byte `json:"data"`
Nonce []byte `json:"nonce"`
}
func startServer() {
fmt.Println("Starting Server...")
l, err := net.Listen("tcp", "127.0.0.1:8080")
if err != nil {
panic(err)
}
defer l.Close()
c, err := l.Accept()
if err != nil {
panic(err)
}
fmt.Println("Client Connected: ", c)
data, err := bufio.NewReader(c).ReadBytes('\n')
if err != nil {
panic(err)
}
var t trans
err_ := json.Unmarshal(data, &t)
if err != nil {
panic(err_)
}
// fmt.Println("Key: ", t.Key)
publicKey, e := ParseRsaPublicKeyFromPemStr(t.Key)
if e != nil {
panic(e)
}
// fmt.Println("Success", publicKey)
var cre creden
cre.Data = GenerateAesKey(32)
cre.Nonce = GenerateAesKey(12)
jsonRes, err := json.Marshal(cre)
if err != nil {
panic(err)
}
cipherText, e_r := RsaEncrypt(*publicKey, string(jsonRes))
if e_r != nil {
panic(e_r)
}
fmt.Println("cipherText: ", len(cipherText), " | ", cipherText)
encodedCipherText := Encode(cipherText)
n, err := c.Write([]byte(encodedCipherText))
if err != nil {
panic(err)
}
fmt.Println("Written back the response. Written Bytes: ", n)
data2, err2 := bufio.NewReader(c).ReadBytes('\n')
if err2 != nil {
panic(err2)
}
var t2 trans
err_2 := json.Unmarshal(data2, &t2)
if err_2 != nil {
panic(err_2)
}
fmt.Println("recv data: ", t2.Key)
cipherText2 := Decode(t2.Key)
fmt.Println("cipherText2: ", cipherText2)
plainText2, err := AesDecryption(cre.Data, cipherText2, cre.Nonce)
if err != nil {
panic(err)
}
fmt.Println("plainText: ", plainText2)
}
func main() {
startServer()
}
Flutter代码
外部库:
-
steel_crypt
flutter pub add steel_crypt
。 -
crypton
flutter pub add crypton
。
只需在Flutter项目中添加以下函数,并在返回MaterialApp()
之前调用它。如果在此级别之下调用此函数,它将在每次窗口刷新时执行。
void connectFunc() async {
Socket socket = await Socket.connect('10.0.2.2', 8080);
print(socket);
print("Connected...");
// listen to the received data event stream
RSAKeypair rsaKeypair = RSAKeypair.fromRandom();
socket.listen((List<int> event) {
String base64Response = utf8.decode(event);
// dynamic response = base64.decode(base64Response);
// print(response.length);
// print(response.runtimeType);
try {
String plainText = rsaKeypair.privateKey.decrypt(base64Response);
print(plainText);
dynamic jsonData = jsonDecode(plainText);
String Key = jsonData["data"];
String Nonce = jsonData["nonce"];
var aes = AesCrypt(key: Key, padding: PaddingAES.pkcs7);
print('AES Symmetric GCM:');
var crypted = aes.gcm.encrypt(inp: 'words', iv: Nonce); //encrypt
// print(crypted);
// print(aes.gcm.decrypt(enc: crypted, iv: Nonce)); //decrypt
// print('');
print("send data: " + crypted);
dynamic dictData = {
"key": crypted,
};
socket.add(utf8.encode(jsonEncode(dictData) + "\n"));
} catch (e) {
print(e);
}
// dynamic response = jsonDecode(jsonResponse);
// String key = response["data"];
// String nonce = response["nonce"];
});
// RSAKeypair rsaKeypair = RSAKeypair.fromRandom();
dynamic dictData = {
"key": rsaKeypair.publicKey.toFormattedPEM(),
};
socket.add(utf8.encode(jsonEncode(dictData) + "\n"));
// send hello
// socket.add(utf8.encode('hello from flutter/dart'));
// return socket;
}
英文:
I'm trying to decrypt the data in golang using the in-inbuild crypto library, the data is encrypted in flutter/dart using steel_crypt library.
The specific message that is thrown by the golang's crypto library is: panic: cipher: message authentication failed
.
I'm running flutter app on Android amulator (localhost is: 10.0.2.2)
> Golang version: go1.17.6 linux/amd64 |
Flutter version: Flutter 2.8.1 • channel stable |
Dart version: Dart 2.15.1
Golang Code
package main
import (
"bufio"
"crypto"
"crypto/aes"
"crypto/cipher"
"crypto/rand"
"crypto/rsa"
"crypto/x509"
"encoding/base64"
"encoding/json"
"encoding/pem"
"errors"
"fmt"
"io"
"net"
)
func Encode(data []byte) string {
hb := base64.StdEncoding.EncodeToString([]byte(data))
return hb
}
// Decoding the base string to array of bytes
func Decode(data string) []byte {
hb, _ := base64.StdEncoding.DecodeString(data)
return hb
}
// Generating RSA private key
func GenerateRsaPrivateKey(size int) (*rsa.PrivateKey, error) {
privateKey, err := rsa.GenerateKey(rand.Reader, size)
if err != nil {
return nil, err
}
return privateKey, nil
}
// Generating RSA public key
func GenerateRsaPublicKey(privateKey *rsa.PrivateKey) rsa.PublicKey {
return privateKey.PublicKey
}
// This function can be use encrypt a plain text with rsa algorithm
func RsaEncrypt(publicKey rsa.PublicKey, data string) ([]byte, error) {
encryptedBytes, err := rsa.EncryptPKCS1v15(
rand.Reader,
&publicKey,
[]byte(data))
return encryptedBytes, err
// encryptedBytes, err := rsa.EncryptOAEP(
// sha256.New(),
// rand.Reader,
// &publicKey,
// []byte(data),
// nil)
// return encryptedBytes, err
}
// This function can be use decrypt a encrypted text with rsa algorithm
func RsaDecrypt(privateKey rsa.PrivateKey, data []byte) ([]byte, error) {
decryptedBytes, err := privateKey.Decrypt(
nil,
data,
&rsa.OAEPOptions{Hash: crypto.SHA256})
return decryptedBytes, err
}
// This fucntion is used to dump/serialize the rsa public key
func DumpKey(key *rsa.PublicKey) ([]byte, error) {
return x509.MarshalPKCS1PublicKey(key), nil
}
// This function is used to load the rsa public key
func LoadKey(byteKey []byte) (*rsa.PublicKey, error) {
key, err := x509.ParsePKCS1PublicKey(byteKey)
return key, err
}
// Generate fixed size byte array
func GenerateAesKey(size int) []byte {
token := make([]byte, size)
rand.Read(token)
return token
}
// This fucntion can be used for encrypting a plain text using AES-GCM algorithm
func AesEncryption(key []byte, data string) ([]byte, error) {
c, err := aes.NewCipher(key)
if err != nil {
return nil, err
}
gcm, err := cipher.NewGCM(c)
if err != nil {
return nil, err
}
nonce := make([]byte, gcm.NonceSize())
if _, err = io.ReadFull(rand.Reader, nonce); err != nil {
return nil, err
}
cipherText := gcm.Seal(nonce, nonce, []byte(data), nil)
return cipherText, nil
}
// This fucntion can be used for decrypting the ciphertext encrypted using AES-GCM algorithm
func AesDecryption(key []byte, cipherText []byte, nonce []byte) ([]byte, error) {
c, err := aes.NewCipher(key)
if err != nil {
fmt.Println("1")
return nil, err
}
gcm, err := cipher.NewGCM(c)
if err != nil {
fmt.Println("2")
return nil, err
}
noncesize := gcm.NonceSize()
if len(cipherText) < noncesize {
fmt.Println("3")
return nil, err
}
cipherText = cipherText[noncesize:]
// nonce, cipherText := cipherText[:noncesize], cipherText[noncesize:]
plainText, err := gcm.Open(nil, nonce, cipherText, nil)
if err != nil {
fmt.Println("4", err.Error())
return nil, err
}
return plainText, nil
}
func ParseRsaPublicKeyFromPemStr(pubPEM string) (*rsa.PublicKey, error) {
block, _ := pem.Decode([]byte(pubPEM))
if block == nil {
return nil, errors.New("failed to parse PEM block containing the key")
}
pub, err := x509.ParsePKIXPublicKey(block.Bytes)
if err != nil {
return nil, err
}
switch pub := pub.(type) {
case *rsa.PublicKey:
return pub, nil
default:
break // fall through
}
return nil, errors.New("Key type is not RSA")
}
type trans struct {
Key string `json:"key"`
}
type creden struct {
Data []byte `json:"data"`
Nonce []byte `json:"nonce"`
}
func startServer() {
fmt.Println("Starting Server...")
l, err := net.Listen("tcp", "127.0.0.1:8080")
if err != nil {
panic(err)
}
defer l.Close()
c, err := l.Accept()
if err != nil {
panic(err)
}
fmt.Println("Client Connected: ", c)
data, err := bufio.NewReader(c).ReadBytes('\n')
if err != nil {
panic(err)
}
var t trans
err_ := json.Unmarshal(data, &t)
if err != nil {
panic(err_)
}
// fmt.Println("Key: ", t.Key)
publicKey, e := ParseRsaPublicKeyFromPemStr(t.Key)
if e != nil {
panic(e)
}
// fmt.Println("Success", publicKey)
var cre creden
cre.Data = GenerateAesKey(32)
cre.Nonce = GenerateAesKey(12)
jsonRes, err := json.Marshal(cre)
if err != nil {
panic(err)
}
cipherText, e_r := RsaEncrypt(*publicKey, string(jsonRes))
if e_r != nil {
panic(e_r)
}
fmt.Println("cipherText: ", len(cipherText), " | ", cipherText)
encodedCipherText := Encode(cipherText)
n, err := c.Write([]byte(encodedCipherText))
if err != nil {
panic(err)
}
fmt.Println("Written back the response. Written Bytes: ", n)
data2, err2 := bufio.NewReader(c).ReadBytes('\n')
if err2 != nil {
panic(err2)
}
var t2 trans
err_2 := json.Unmarshal(data2, &t2)
if err_2 != nil {
panic(err_2)
}
fmt.Println("recv data: ", t2.Key)
cipherText2 := Decode(t2.Key)
fmt.Println("cipherText2: ", cipherText2)
plainText2, err := AesDecryption(cre.Data, cipherText2, cre.Nonce)
if err != nil {
panic(err)
}
fmt.Println("plainText: ", plainText2)
}
func main() {
startServer()
}
Flutter Code
External Libraries:
-
steel_crypt
flutter pub add steel_crypt
. -
crypton
flutter pub add crypton
.
Just add below function in your flutter project and call it just before returning the MaterialApp()
. If you call this function below this level it will get executed every time windows refres.
void connectFunc() async {
Socket socket = await Socket.connect('10.0.2.2', 8080);
print(socket);
print("Connected...");
// listen to the received data event stream
RSAKeypair rsaKeypair = RSAKeypair.fromRandom();
socket.listen((List<int> event) {
String base64Response = utf8.decode(event);
// dynamic response = base64.decode(base64Response);
// print(response.length);
// print(response.runtimeType);
try {
String plainText = rsaKeypair.privateKey.decrypt(base64Response);
print(plainText);
dynamic jsonData = jsonDecode(plainText);
String Key = jsonData["data"];
String Nonce = jsonData["nonce"];
var aes = AesCrypt(key: Key, padding: PaddingAES.pkcs7);
print('AES Symmetric GCM:');
var crypted = aes.gcm.encrypt(inp: 'words', iv: Nonce); //encrypt
// print(crypted);
// print(aes.gcm.decrypt(enc: crypted, iv: Nonce)); //decrypt
// print('');
print("send data: " + crypted);
dynamic dictData = {
"key": crypted,
};
socket.add(utf8.encode(jsonEncode(dictData) + "\n"));
} catch (e) {
print(e);
}
// dynamic response = jsonDecode(jsonResponse);
// String key = response["data"];
// String nonce = response["nonce"];
});
// RSAKeypair rsaKeypair = RSAKeypair.fromRandom();
dynamic dictData = {
"key": rsaKeypair.publicKey.toFormattedPEM(),
};
socket.add(utf8.encode(jsonEncode(dictData) + "\n"));
// send hello
// socket.add(utf8.encode('hello from flutter/dart'));
// return socket;
}
答案1
得分: 1
我已经找到了问题的解决方案。解决方案是在Flutter/Dart中使用另一个名为cryptography的库来加密数据。在Golang方面没有错误(除了一些修改)。
在Golang端修改了AesDecrypt函数:
func AesDecryption(key []byte, cipherText []byte, nonce []byte) ([]byte, error) {
c, err := aes.NewCipher(key)
if err != nil {
fmt.Println("1")
return nil, err
}
gcm, err := cipher.NewGCM(c)
if err != nil {
fmt.Println("2")
return nil, err
}
// noncesize := gcm.NonceSize()
// if len(cipherText) < noncesize {
// fmt.Println("3")
// return nil, err
// }
// cipherText = cipherText[noncesize:]
// nonce, cipherText := cipherText[:noncesize], cipherText[noncesize:]
plainText, err := gcm.Open(nil, nonce, cipherText, nil)
if err != nil {
fmt.Println("4", err.Error())
return nil, err
}
return plainText, nil
}
现在整个修改后的startServer函数如下:
func startServer(nonce []byte, key []byte) {
fmt.Println("Starting Server...")
l, err := net.Listen("tcp", "127.0.0.1:8080")
if err != nil {
panic(err)
}
defer l.Close()
c, err := l.Accept()
if err != nil {
panic(err)
}
fmt.Println("Client Connected: ", c)
data, err := bufio.NewReader(c).ReadBytes('\n')
if err != nil {
panic(err)
}
var t trans
err_ := json.Unmarshal(data, &t)
if err != nil {
panic(err_)
}
// fmt.Println("Key: ", t.Key)
publicKey, e := ParseRsaPublicKeyFromPemStr(t.Key)
if e != nil {
panic(e)
}
// fmt.Println("Success", publicKey)
var cre creden
cre.Data = Encode(key) //GenerateAesKey(32)
cre.Nonce = Encode(nonce) //GenerateAesKey(12)
jsonRes, err := json.Marshal(cre)
if err != nil {
panic(err)
}
cipherText, e_r := RsaEncrypt(*publicKey, string(jsonRes))
if e_r != nil {
panic(e_r)
}
// fmt.Println("cipherText: ", len(cipherText), " | ", cipherText)
encodedCipherText := Encode(cipherText)
n, err := c.Write([]byte(encodedCipherText))
if err != nil {
panic(err)
}
fmt.Println("Written back the response. Written Bytes: ", n)
data2, err2 := bufio.NewReader(c).ReadBytes('\n')
if err2 != nil {
panic(err2)
}
var t2 trans
err_2 := json.Unmarshal(data2, &t2)
if err_2 != nil {
panic(err_2)
}
fmt.Println("recv data: ", t2.Key)
cipherText2 := Decode(t2.Key)
fmt.Println("cipherText2: ", cipherText2)
plainText2, err := AesDecryption(key, cipherText2, nonce)
if err != nil {
panic(err)
}
fmt.Println("plainText: ", string(plainText2))
}
现在解决方案的Flutter部分如下:
外部依赖:cryptography: ^2.0.5
void connectFunc() async {
Socket socket = await Socket.connect('10.0.2.2', 8080);
print(socket);
print("Connected...");
// listen to the received data event stream
RSAKeypair rsaKeypair = RSAKeypair.fromRandom();
socket.listen((List<int> event) async {
String base64Response = utf8.decode(event);
try {
String plainText = rsaKeypair.privateKey.decrypt(base64Response);
dynamic jsonData = jsonDecode(plainText);
String Key = jsonData["data"];
String Nonce = jsonData["nonce"];
String message = "Hello World";
final algorithm = AesGcm.with256bits();
final secretBox = await algorithm.encrypt(
message.codeUnits,
secretKey: SecretKey(base64.decode(jsonData["data"])),
nonce: base64.decode(jsonData["nonce"]),
);
print("key: ${base64.decode(jsonData["data"])}");
print("nonce: ${base64.decode(jsonData["nonce"])}");
print("secretBox: ${secretBox.concatenation(nonce: false)}");
dynamic dictData = {
"key": base64.encode(secretBox.concatenation(nonce: false)),
};
socket.add(utf8.encode(jsonEncode(dictData) + "\n"));
} catch (e) {
print(e);
}
});
dynamic dictData = {
"key": rsaKeypair.publicKey.toFormattedPEM(),
};
socket.add(utf8.encode(jsonEncode(dictData) + "\n"));
}
英文:
I have found the solution of the problem.
The solution is that we have to use another library called cryptography to encrypt the data in flutter/dart.
There is no error at golang side ( except some modifications ).
AesDecrypt function at the golang side have been modified
func AesDecryption(key []byte, cipherText []byte, nonce []byte) ([]byte, error) {
c, err := aes.NewCipher(key)
if err != nil {
fmt.Println("1")
return nil, err
}
gcm, err := cipher.NewGCM(c)
if err != nil {
fmt.Println("2")
return nil, err
}
// noncesize := gcm.NonceSize()
// if len(cipherText) < noncesize {
// fmt.Println("3")
// return nil, err
// }
// cipherText = cipherText[noncesize:]
// nonce, cipherText := cipherText[:noncesize], cipherText[noncesize:]
plainText, err := gcm.Open(nil, nonce, cipherText, nil)
if err != nil {
fmt.Println("4", err.Error())
return nil, err
}
return plainText, nil
}
Now the whole revised startServer function in here:
func startServer(nonce []byte, key []byte) {
fmt.Println("Starting Server...")
l, err := net.Listen("tcp", "127.0.0.1:8080")
if err != nil {
panic(err)
}
defer l.Close()
c, err := l.Accept()
if err != nil {
panic(err)
}
fmt.Println("Client Connected: ", c)
data, err := bufio.NewReader(c).ReadBytes('\n')
if err != nil {
panic(err)
}
var t trans
err_ := json.Unmarshal(data, &t)
if err != nil {
panic(err_)
}
// fmt.Println("Key: ", t.Key)
publicKey, e := ParseRsaPublicKeyFromPemStr(t.Key)
if e != nil {
panic(e)
}
// fmt.Println("Success", publicKey)
var cre creden
cre.Data = Encode(key) //GenerateAesKey(32)
cre.Nonce = Encode(nonce) //GenerateAesKey(12)
jsonRes, err := json.Marshal(cre)
if err != nil {
panic(err)
}
cipherText, e_r := RsaEncrypt(*publicKey, string(jsonRes))
if e_r != nil {
panic(e_r)
}
// fmt.Println("cipherText: ", len(cipherText), " | ", cipherText)
encodedCipherText := Encode(cipherText)
n, err := c.Write([]byte(encodedCipherText))
if err != nil {
panic(err)
}
fmt.Println("Written back the response. Written Bytes: ", n)
data2, err2 := bufio.NewReader(c).ReadBytes('\n')
if err2 != nil {
panic(err2)
}
var t2 trans
err_2 := json.Unmarshal(data2, &t2)
if err_2 != nil {
panic(err_2)
}
fmt.Println("recv data: ", t2.Key)
cipherText2 := Decode(t2.Key)
fmt.Println("cipherText2: ", cipherText2)
plainText2, err := AesDecryption(key, cipherText2, nonce)
if err != nil {
panic(err)
}
fmt.Println("plainText: ", string(plainText2))
}
And now the flutter side of solution:
external denepencies: cryptography: ^2.0.5
void connectFunc() async {
Socket socket = await Socket.connect('10.0.2.2', 8080);
print(socket);
print("Connected...");
// listen to the received data event stream
RSAKeypair rsaKeypair = RSAKeypair.fromRandom();
socket.listen((List<int> event) async {
String base64Response = utf8.decode(event);
try {
String plainText = rsaKeypair.privateKey.decrypt(base64Response);
dynamic jsonData = jsonDecode(plainText);
String Key = jsonData["data"];
String Nonce = jsonData["nonce"];
String message = "Hello World";
final algorithm = AesGcm.with256bits();
final secretBox = await algorithm.encrypt(
message.codeUnits,
secretKey: SecretKey(base64.decode(jsonData["data"])),
nonce: base64.decode(jsonData["nonce"]),
);
print("key: ${base64.decode(jsonData["data"])}");
print("nonce: ${base64.decode(jsonData["nonce"])}");
print("secretBox: ${secretBox.concatenation(nonce: false)}");
dynamic dictData = {
"key": base64.encode(secretBox.concatenation(nonce: false)),
};
socket.add(utf8.encode(jsonEncode(dictData) + "\n"));
} catch (e) {
print(e);
}
});
dynamic dictData = {
"key": rsaKeypair.publicKey.toFormattedPEM(),
};
socket.add(utf8.encode(jsonEncode(dictData) + "\n"));
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论