gpt4 book ai didi

c# - 在 C# 中加密文件并在 flutter 中解密

转载 作者:行者123 更新时间:2023-12-05 03:57:17 27 4
gpt4 key购买 nike

我使用 RijndaelManaged 在 c# 代码中加密了一个文件,它在 System.Security.Cryptography 中可用。该文件需要传输到使用 dart/flutter 开发的移动应用程序,我需要使用 dart 代码对其进行解密并将其呈现给用户。如何做到这一点?

下面显示的是用 C# 进行加密的代码:

            string password = keyPhrase; // Your Key Here
UnicodeEncoding UE = new UnicodeEncoding();
byte[] key = UE.GetBytes(password);

string cryptFile = outputFile;
FileStream fsCrypt = new FileStream(cryptFile, FileMode.Create);

RijndaelManaged RMCrypto = new RijndaelManaged();

CryptoStream cs = new CryptoStream(fsCrypt,
RMCrypto.CreateEncryptor(key, key),
CryptoStreamMode.Write);

FileStream fsIn = new FileStream(inputFile, FileMode.Open);

int data;
while ((data = fsIn.ReadByte()) != -1)
cs.WriteByte((byte)data);


fsIn.Close();
cs.Close();
fsCrypt.Close();

谢谢

最佳答案

我遇到了同样的问题。几个小时后,找到了解决方案。我的代码基于此 question1question2 C#上的代码

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Security.Cryptography;

namespace ConsoleApplication2
{
class Program
{
static void Main(string[] args)
{
var m_strPassPhrase = "YYYYYYYYYYYYYYYYYYY";
var p_strSaltValue = "XXXXXXXXXXXXXXXXX";
var m_strPasswordIterations = 2;
var m_strInitVector = "ZZZZZZZZZZZZZZZZ";
var plainText = "myPassword";
var blockSize = 32;
var saltValueBytes = Encoding.ASCII.GetBytes(p_strSaltValue);
var password = new Rfc2898DeriveBytes(m_strPassPhrase, saltValueBytes, m_strPasswordIterations);
var keyBytes = password.GetBytes(blockSize);

var symmetricKey = new RijndaelManaged();

var initVectorBytes = Encoding.ASCII.GetBytes(m_strInitVector);
var encryptor = symmetricKey.CreateEncryptor(keyBytes, initVectorBytes);

var memoryStream = new System.IO.MemoryStream();
var cryptoStream = new CryptoStream(memoryStream, encryptor, CryptoStreamMode.Write);

var plainTextBytes = Encoding.UTF8.GetBytes(plainText);

cryptoStream.Write(plainTextBytes, 0, plainTextBytes.Length);
cryptoStream.FlushFinalBlock();

var cipherTextBytes = memoryStream.ToArray();
memoryStream.Close();
cryptoStream.Close();

var cipherText = Convert.ToBase64String(cipherTextBytes);

Console.WriteLine(cipherText);

Console.WriteLine("\n end");
}
}
}

对于 flutter,你可以使用 pointycastleDart 代码(使用 decryptString 和 cryptString 方法):

import 'dart:convert';
import 'package:pointycastle/block/aes_fast.dart';
import 'dart:typed_data';
import 'package:pointycastle/export.dart';
import 'package:pointycastle/key_derivators/pbkdf2.dart';
import 'package:pointycastle/paddings/pkcs7.dart';
import 'package:pointycastle/pointycastle.dart';

const KEY_SIZE = 32; // 32 byte key for AES-256
const ITERATION_COUNT = 2;
const SALT = "XXXXXXXXXXXXXXXXX";
const INITIAL_VECTOR = "ZZZZZZZZZZZZZZZZ";
const PASS_PHRASE = "YYYYYYYYYYYYYYYYYYY";

Future<String> cryptString(String text) async {
String encryptedString = "";

final mStrPassPhrase = toUtf8(PASS_PHRASE);

encryptedString =
AesHelper.encrypt(mStrPassPhrase, toUtf8(text), mode: AesHelper.CBC_MODE);

return encryptedString;
}

Future<String> decryptString(String text) async {
String decryptedString = "";

final mStrPassPhrase = toUtf8(PASS_PHRASE);

decryptedString =
AesHelper.decrypt(mStrPassPhrase, toUtf8(text), mode: AesHelper.CBC_MODE);

return decryptedString;
}

///MARK: AesHelper class
class AesHelper {
static const CBC_MODE = 'CBC';
static const CFB_MODE = 'CFB';

static Uint8List deriveKey(dynamic password,
{String salt = '',
int iterationCount = ITERATION_COUNT,
int derivedKeyLength = KEY_SIZE}) {
if (password == null || password.isEmpty) {
throw new ArgumentError('password must not be empty');
}

if (password is String) {
password = createUint8ListFromString(password);
}

Uint8List saltBytes = createUint8ListFromString(salt);
Pbkdf2Parameters params =
new Pbkdf2Parameters(saltBytes, iterationCount, derivedKeyLength);
KeyDerivator keyDerivator =
new PBKDF2KeyDerivator(new HMac(new SHA1Digest(), 64));
keyDerivator.init(params);

return keyDerivator.process(password);
}

static Uint8List pad(Uint8List src, int blockSize) {
var pad = new PKCS7Padding();
pad.init(null);

int padLength = blockSize - (src.length % blockSize);
var out = new Uint8List(src.length + padLength)..setAll(0, src);
pad.addPadding(out, src.length);

return out;
}

static Uint8List unpad(Uint8List src) {
var pad = new PKCS7Padding();
pad.init(null);

int padLength = pad.padCount(src);
int len = src.length - padLength;

return new Uint8List(len)..setRange(0, len, src);
}

static String encrypt(String password, String plaintext,
{String mode = CBC_MODE}) {
String salt = toASCII(SALT);
Uint8List derivedKey = deriveKey(password, salt: salt);
KeyParameter keyParam = new KeyParameter(derivedKey);
BlockCipher aes = new AESFastEngine();

var ivStr = toASCII(INITIAL_VECTOR);
Uint8List iv =
createUint8ListFromString(ivStr);

BlockCipher cipher;
ParametersWithIV params = new ParametersWithIV(keyParam, iv);
switch (mode) {
case CBC_MODE:
cipher = new CBCBlockCipher(aes);
break;
case CFB_MODE:
cipher = new CFBBlockCipher(aes, aes.blockSize);
break;
default:
throw new ArgumentError('incorrect value of the "mode" parameter');
break;
}
cipher.init(true, params);

Uint8List textBytes = createUint8ListFromString(plaintext);
Uint8List paddedText = pad(textBytes, aes.blockSize);
Uint8List cipherBytes = _processBlocks(cipher, paddedText);

return base64.encode(cipherBytes);
}

static String decrypt(String password, String ciphertext,
{String mode = CBC_MODE}) {
String salt = toASCII(SALT);
Uint8List derivedKey = deriveKey(password, salt: salt);
KeyParameter keyParam = new KeyParameter(derivedKey);
BlockCipher aes = new AESFastEngine();

var ivStr = toASCII(INITIAL_VECTOR);
Uint8List iv = createUint8ListFromString(ivStr);
Uint8List cipherBytesFromEncode = base64.decode(ciphertext);

Uint8List cipherIvBytes =
new Uint8List(cipherBytesFromEncode.length + iv.length)
..setAll(0, iv)
..setAll(iv.length, cipherBytesFromEncode);

BlockCipher cipher;

ParametersWithIV params = new ParametersWithIV(keyParam, iv);
switch (mode) {
case CBC_MODE:
cipher = new CBCBlockCipher(aes);
break;
case CFB_MODE:
cipher = new CFBBlockCipher(aes, aes.blockSize);
break;
default:
throw new ArgumentError('incorrect value of the "mode" parameter');
break;
}
cipher.init(false, params);

int cipherLen = cipherIvBytes.length - aes.blockSize;
Uint8List cipherBytes = new Uint8List(cipherLen)
..setRange(0, cipherLen, cipherIvBytes, aes.blockSize);
Uint8List paddedText = _processBlocks(cipher, cipherBytes);
Uint8List textBytes = unpad(paddedText);

return new String.fromCharCodes(textBytes);
}

static Uint8List _processBlocks(BlockCipher cipher, Uint8List inp) {
var out = new Uint8List(inp.lengthInBytes);

for (var offset = 0; offset < inp.lengthInBytes;) {
var len = cipher.processBlock(inp, offset, out, offset);
offset += len;
}

return out;
}
}

///MARK: HELPERS
Uint8List createUint8ListFromString(String s) {
Uint8List ret = Uint8List.fromList(s.codeUnits);

return ret;
}

String toUtf8(value) {
var encoded = utf8.encode(value);
var decoded = utf8.decode(encoded);
return decoded;
}

String toASCII(value) {
var encoded = ascii.encode(value);
var decoded = ascii.decode(encoded);
return decoded;
}

关于c# - 在 C# 中加密文件并在 flutter 中解密,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58677959/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com