[英]encrypt/decrypt file and Incorrect data
static void encrypt() throws IOException, NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException {
// Here you read the cleartext.
FileInputStream fis = new FileInputStream("data/cleartext");
// This stream write the encrypted text. This stream will be wrapped by another stream.
FileOutputStream fos = new FileOutputStream("data/encrypted");
// Length is 16 byte
SecretKeySpec sks = new SecretKeySpec("MyDifficultPassw".getBytes(), "AES");
// Create cipher
Cipher cipher = Cipher.getInstance("AES");
cipher.init(Cipher.ENCRYPT_MODE, sks);
// Wrap the output stream
CipherOutputStream cos = new CipherOutputStream(fos, cipher);
// Write bytes
int b;
byte[] d = new byte[8];
while((b = fis.read(d)) != -1) {
cos.write(d, 0, b);
}
// Flush and close streams.
cos.flush();
cos.close();
fis.close();
}
static void decrypt() throws IOException, NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException {
FileInputStream fis = new FileInputStream("data/encrypted");
FileOutputStream fos = new FileOutputStream("data/decrypted");
SecretKeySpec sks = new SecretKeySpec("MyDifficultPassw".getBytes(), "AES");
Cipher cipher = Cipher.getInstance("AES");
cipher.init(Cipher.DECRYPT_MODE, sks);
CipherInputStream cis = new CipherInputStream(fis, cipher);
int b;
byte[] d = new byte[8];
while((b = cis.read(d)) != -1) {
fos.write(d, 0, b);
}
fos.flush();
fos.close();
cis.close();
}
I am using these functions for encrypt/ decrypt file, but on some devices I get incorrect data. 我正在使用这些功能来加密/解密文件,但是在某些设备上我得到了不正确的数据。
for example, my correct data is : 例如,我的正确数据是:
one 一
two 二
three 三
four 四
five 五
after decrypt : 解密后:
one 一
two 二
three 三
൰Ẓ㫩 ൰Ẓ㫩
൰Ẓ㫩 ൰Ẓ㫩
I have used postDelayed() function But it did not matter ! 我已经使用了postDelayed()函数,但这没关系!
decrypt();
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
// TODO Auto-generated method stub
getContentsFile();
}
}, 7000);
the file size is 80 Kilobytes! 文件大小为80千字节!
it had problem on emulator!! 在模拟器上有问题!! it had problem on samsung gt-s7562, but on galaxy s4 everything is ok !! 它在三星GT-S7562上有问题,但在银河S4上一切正常!
I see at least two potential platform compatibility issues with your code: 我发现您的代码至少存在两个潜在的平台兼容性问题:
Never call getBytes()
without declaring a charset: 在未声明字符集的情况下,切勿调用getBytes()
:
SecretKeySpec sks = new SecretKeySpec("MyDifficultPassw".getBytes(), "AES");
should be: (eg) 应该是:(例如)
SecretKeySpec sks = new SecretKeySpec( "MyDifficultPassw".getBytes("UTF-8"), "AES");
Always specify a complete transformation, eg "AES/CBC/PKCS5Padding": 始终指定完整的转换,例如“ AES / CBC / PKCS5Padding”:
Cipher cipher = Cipher.getInstance("AES");
should be (eg) 应该是 (例如)
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
This alone could be the cause of your problem. 仅此一个可能是您的问题的原因。 Different platforms have different default character sets, which means you would get a different string of bytes for your key. 不同的平台具有不同的默认字符集,这意味着您将为密钥获得不同的字节字符串。
Less commonly, different crypto providers have different defaults when you selet "AES"
. 不太常见的是,当您选择"AES"
时,不同的加密提供程序具有不同的默认值。 Some will do ECB-mode encryption, some will do CBC-mode encryption. 有些将执行ECB模式加密,有些将进行CBC模式加密。 It's always safest to declare exactly what you want. 确切地声明您想要的东西总是最安全的。
Side note: you really shouldn't be creating a key from the raw bytes of a string. 旁注:您实际上不应该从字符串的原始字节创建键。 Use a password derivation method instead, such as PBKDF2. 请改用密码派生方法,例如PBKDF2。
I'm using these two methods for encrypt/decrypt and they work perfectly to me on any device. 我正在使用这两种方法进行加密/解密,它们对我在任何设备上都能正常工作。 It's done a slightly different way than you so try comparing both approaches to see what could be working wrong. 它的执行方式与您稍有不同,因此请尝试比较两种方法以查看可能出了什么问题。
For encryption : 对于加密 :
Gets : iv
vector and the message
to encrypt: 获取 : iv
矢量和要加密的message
:
public String getEncrypt(final byte[] iv, final String message) throws GeneralSecurityException, NullPointerException {
if (key.isEmpty())
throw new NullPointerException();
final byte[] rawData = key.getBytes(Charset.forName("US-ASCII"));
if (rawData.length != 16) {
// If this is not 16 in length, there's a problem with the key size, nothing to do here
throw new IllegalArgumentException("You've provided an invalid key size");
}
final SecretKeySpec seckeySpec = new SecretKeySpec(rawData, "AES");
final Cipher ciph = Cipher.getInstance("AES/CBC/PKCS5Padding");
ciph.init(Cipher.ENCRYPT_MODE, seckeySpec, new IvParameterSpec(iv));
byte[] encryptedBA = ciph.doFinal(message.getBytes(Charset.forName("US-ASCII")));
try {
final String encryptedText = new String(Base64.encode(encryptedBA, Base64.DEFAULT), "UTF-8");
return encryptedText.toString();
}
catch (final UnsupportedEncodingException e1) { }
return "";
}
For decryption: 对于解密:
public String getDecrypt(final byte[] encrypted) throws GeneralSecurityException, NullPointerException {
if (key.isEmpty())
throw new NullPointerException();
final byte[] rawData = key.getBytes(Charset.forName("US-ASCII"));
if (rawData.length != 16) {
// If this is not 16 in length, there's a problem with the key size, nothing to do here
throw new IllegalArgumentException("Invalid key size.");
}
final SecretKeySpec seckeySpec = new SecretKeySpec(rawData, "AES");
final Cipher ciph = Cipher.getInstance("AES/CBC/PKCS5Padding");
ciph.init(Cipher.DECRYPT_MODE, seckeySpec, new IvParameterSpec(new byte[16]));
final byte[] decryptedmess = ciph.doFinal(encrypted);
return new String(decryptedmess, Charset.forName("US-ASCII"));
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.