gpt4 book ai didi

c# - 如何在 .net 中加密文件并在 android 中解密

转载 作者:塔克拉玛干 更新时间:2023-11-02 21:03:46 24 4
gpt4 key购买 nike

我一直在做一个项目,我们必须在 android sd 卡中安全地保存一个 pdf。我们希望它在 .net 中加密,因为它必须通过 API 传输。我已经在 .NET 中实现,但无法在 android 中解密。

加密文件的代码

public static void EncryptFile(string inputFile, string outputFile)
{
try
{
string password = @"myKey123"; // 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();
RMCrypto.Mode = CipherMode.CBC; //remember this parameter
RMCrypto.Padding = PaddingMode.PKCS7; //remember this parameter
RMCrypto.KeySize = 0x80;
RMCrypto.BlockSize = 0x80;
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();

}
catch
{
Console.WriteLine("Encryption failed!", "Error");
}
}

解密文件的代码

public  static void DecryptFile(string inputFile, string outputFile)
{

{
string password = @"myKey123"; // Your Key Here

UnicodeEncoding UE = new UnicodeEncoding();
byte[] key = UE.GetBytes(password);



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

RijndaelManaged RMCrypto = new RijndaelManaged();
RMCrypto.Mode = CipherMode.CBC; //remember this parameter
RMCrypto.Padding = PaddingMode.PKCS7; //remember this parameter
RMCrypto.KeySize = 0x80;
RMCrypto.BlockSize = 0x80;
CryptoStream cs = new CryptoStream(fsCrypt,
RMCrypto.CreateDecryptor(key, key),
CryptoStreamMode.Read);

FileStream fsOut = new FileStream(outputFile, FileMode.Create);

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

fsOut.Close();
cs.Close();
fsCrypt.Close();

}
}

我在 Android 中尝试使用以下代码

public static byte[] decodeFile(String key, byte[] fileData) throws Exception
{
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); //this parameters should not be changed
byte[] keyBytes = new byte[16];
byte[] b = key.getBytes("UTF-16");
System.out.println("RAM"+b);
int len = b.length;
if (len > keyBytes.length)
len = keyBytes.length;
System.arraycopy(b, 0, keyBytes, 0, len);
SecretKeySpec keySpec = new SecretKeySpec(keyBytes, "AES");
IvParameterSpec ivSpec = new IvParameterSpec(keyBytes);
cipher.init(Cipher.DECRYPT_MODE, keySpec, ivSpec);
byte[] decrypted = cipher.doFinal(fileData);
return decrypted;
}

运行这段代码时出现错误:

error:06065064:digital envelope routines:EVP_DecryptFinal_ex:bad decrypt

最佳答案

所以我发现您的代码和您使用的架构存在问题。当您选择在不同语言程序和不同环境(Android(“unix”)和 Windows)中加密文件时,您需要记住小端和大端的概念。 - the wikipedia Endianness

Aperently 在 Java 中,它总是使用 BIG endian 的威胁,因此最高有效字节 (MSB) 与使用最低有效字节 (LSB) 的 C# 不同,此步骤导致难以追踪的问题。

我基于您的代码创建了一个代码,但使用的是 Java 而不是 android,并且无法使代码正常工作,因为我总是收到相同的错误消息 BadPaddingException: Given final block not properly padded。错误消息并没有说明 key 文件的真正问题。
当您使用 Java 阅读时,它与 .NET 不同,因为当您将 key 转换为字节时,Java 体系结构会威胁到 MSB,而您的真实 key 使用的是 LSB。

所以真正的答案是这个 你需要将你的 key 转换为字节数组,告诉你使用最低有效字节,这样你在 .NET 和 Java 中总是有相同的字节数组
是这样的:

//the bKey it's the array of bytes and the key it's the String your are using.
byte[] bKey = key.getBytes("UTF-16LE");



我发现了 LE 的问题,因为我从 .NET 和 Java 读取了字节数组,它们不同,所以这让我开始发现这个问题

祝你的系统好运!

Ps.:我在解码时遇到了问题,因为解码和解码字节数组时遇到了问题。我找到了一条路径,您应该使用 Apache Commons Base64 来解码 Java 中的字符串。
引用资料

-Big/Little endian - Difference between Big Endian and little Endian Byte order
-填充错误-BadPaddingException: Given final block not properly padded
-提示问题出在关键 - Given final block not properly padded
-解码Base64 - Decoding a Base64 string in Java




我用来测试的代码。

    import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.charset.Charset;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;

public class HelloWorld {

public static void main(String[] args) throws Exception {
// TODO Auto-generated method stub
Path p = Paths
.get("C:\\Users\\casilva\\workspace\\StackOverflow\\src\\tst.enc");

byte[] a = Files.readAllBytes(p);
byte[] result = decodeFile("myKey123", a);
System.out.println("Result=" + new String(result, "UTF-8"));
}


public static byte[] decodeFile(String key, byte[] fileData)
throws Exception {
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
byte[] bKey = key.getBytes("UTF-16LE");

SecretKeySpec keySpec = new SecretKeySpec(bKey, "AES");

IvParameterSpec ivSpec = new IvParameterSpec(bKey);

cipher.init(Cipher.DECRYPT_MODE, keySpec, ivSpec);

byte[] decrypted = cipher.doFinal(fileData);

return decrypted;
}

}

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

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