【发布时间】:2015-11-26 16:24:33
【问题描述】:
我一直在做一个项目,我们必须将 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");
}
}
解密文件的代码
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
【问题讨论】:
-
跳出来的两件事:1)不应该任意截断key数组; 2) PKCS7 是 .NET 代码中使用的填充方案,而 PKCS5 是 android 代码中的填充方案。
-
我也注意到了填充。 PKCS5 是 PKCS7 的子集,因此无法保证您的解密代码能够破译它(有时可能确实有效,但可能被认为是侥幸)。
-
可以做些什么来解决这个问题。任何可以提供帮助的代码或库
-
在 Java 中,使用
PKCS5会导致用于填充的密码的块大小,在本例中为 16 字节,所以这很好。但是,如果您使用相同的密钥加密多个明文,您应该使用不同的 IV。另外,我建议您检查您的要求/您真正想做的事情。如果传输加密文件,密钥如何传输等?
标签: c# android algorithm encryption