Pra*_*ash 6 c# encryption algorithm android
我一直致力于项目,我们必须安全地将PDF保存在android sd卡中.我们希望在.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");
}
}
Run Code Online (Sandbox Code Playgroud)
代码解密文件
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();
}
}
Run Code Online (Sandbox Code Playgroud)
我使用下面的代码在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;
}
Run Code Online (Sandbox Code Playgroud)
运行此代码时出现错误:
error:06065064:digital envelope routines:EVP_DecryptFinal_ex:bad decrypt
Run Code Online (Sandbox Code Playgroud)
小智 5
所以我发现您的代码和您使用的架构存在问题。当您选择在不同语言程序和不同环境(Android(“unix”)和 Windows)中加密文件时,您需要记住小端和大端的概念。
- 维基百科 Endianness。
显然,在 Java 中,it 威胁总是使用 BIG endian,因此最重要的字节 (MSB) 与使用最低有效字节 (LSB) 的 C# 不同,这一步会导致难以追踪的问题。
我根据您的代码创建了一个代码,但使用的是 Java 而不是 android 并且无法使代码工作,因为我总是有相同的错误消息BadPaddingException: Given final block not properly padded。错误消息并没有说明key文件的真正问题。
当您使用 Java 阅读时,它与 .NET 不同,因为当您将密钥转换为字节时,Java 体系结构会使用 MSB 威胁,而真正的密钥使用 LSB。
所以真正的答案you need to convert your key to array of bytes telling to use the Least significative byte so you always have the same array of bytes in .NET and in 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");
Run Code Online (Sandbox Code Playgroud)
I found the issue with the LE because i read the array of bytes from .NET and from Java and they are different so this gave me the start to find this issue
祝你的系统好运!
Ps.:我在解码时遇到了问题,因为您在解码和解码字节数组时遇到了问题。我找到了一条路径,您应该使用 Apache Commons Base64 来解码 Java 中的字符串。
参考文献
-Big/Little endian - Big Endian 和 Little Endian 字节顺序之间的区别
-
填充错误 - BadPaddingException:给定最终块未正确填充
- 问题在于关键 -给定最终块未正确填充
-Decode Base64 -解码Java 中的 Base64 字符串
我用来测试的代码。
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;
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1022 次 |
| 最近记录: |