[英]How to do Encryption and Decryption with RSA in android
我正在尝试使用Helper类RSAHelper.java
加密和解密图像文件
package com.lib;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.security.KeyFactory;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import javax.crypto.Cipher;
import static javax.crypto.Cipher.DECRYPT_MODE;
import static javax.crypto.Cipher.ENCRYPT_MODE;
/**
* Created by shobhan.
*/
public class RSAHelper {
private final static String RSA = "RSA";
private PublicKey publicKey;
private PrivateKey privateKey;
public RSAHelper() throws Exception {
/**
* generate RSA keys
*/
generateKey();
}
private void generateKey() throws Exception {
KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance(RSA);
keyPairGenerator.initialize(1024);
KeyPair keyPair = keyPairGenerator.generateKeyPair();
publicKey = keyPair.getPublic();
privateKey = keyPair.getPrivate();
}
/**
* Used to do encryptFile the file
*
* @param srcPath File path to be encrypted
* @param destPath Encrypts the file in srcPath and creates a file in destPath
* @return true if encryption success, false otherwise
*/
public boolean encryptFile(String srcPath, String destPath) {
try {
FileInputStream fileInputStream = new FileInputStream(srcPath);
FileOutputStream fileOutputStream = new FileOutputStream(destPath);
// byte[] key = "12345678".getBytes();
// SecretKeySpec keySpec = new SecretKeySpec(key, ALGORITHM);
Cipher cipher = Cipher.getInstance(RSA);
cipher.init(Cipher.PUBLIC_KEY, publicKey);
cipher.init(Cipher.ENCRYPT_MODE, publicKey);
// cipher.init(Cipher.ENCRYPT_MODE, keySpec);
// CipherOutputStream cipherOutputStream = new
// CipherOutputStream(fileOutputStream, cipher);
byte[] buf = new byte[117];
byte[] encryptedData = null;
int read;
while ((read = fileInputStream.read(buf)) > 0) {
encryptedData = cipher.doFinal(buf);
fileOutputStream.write(encryptedData);
// cipherOutputStream.write(buf);
}
fileInputStream.close();
fileOutputStream.flush();
// cipherOutputStream.close();
return true;
} catch (Exception e) {
e.printStackTrace();
}
return false;
}
/**
* Used to do decryptFile the file
*
* @param srcPath File path to be decrypted
* @param destPath Decrypts the file in srcPath and creates a file in destPath
* @return true if encryption success, false otherwise
*/
public boolean decryptFile(String srcPath, String destPath) {
try {
FileInputStream fileInputStream = new FileInputStream(srcPath);
FileOutputStream fileOutputStream = new FileOutputStream(destPath);
// byte[] key = "12345678".getBytes();
// SecretKeySpec keySpec = new SecretKeySpec(key, ALGORITHM);
Cipher cipher = Cipher.getInstance(RSA);
cipher.init(Cipher.PRIVATE_KEY, privateKey);
cipher.init(Cipher.DECRYPT_MODE, privateKey);
// cipher.init(Cipher.DECRYPT_MODE, keySpec);
// CipherOutputStream cipherOutputStream = new
// CipherOutputStream(fileOutputStream, cipher);
byte[] buf = new byte[128];
byte[] decryptedData = null;
int read;
while ((read = fileInputStream.read(buf)) > 0) {
decryptedData = cipher.doFinal(buf);
fileOutputStream.write(decryptedData);
// cipherOutputStream.write(buf);
}
fileInputStream.close();
fileOutputStream.flush();
return true;
} catch (Exception e) {
e.printStackTrace();
}
return false;
}
}
在我以前喜欢的活动中
RSAHelper rsaHelper = null;
try {
rsaHelper = new RSAHelper();
} catch (Exception e) {
e.printStackTrace();
}
String src = getExternalFilesDir("sdcard").getAbsolutePath() + "/mother.png";
String dest = src.replace("mother","motherEnc");
String decrypted = dest.replace("motherEnc","motherDec");
rsaHelper.encryptFile(src, dest);
rsaHelper.decryptFile(dest, decrypted);
但是decrypted
文件不是原始文件(意味着已损坏)。
在Windows桌面中执行时,相同的代码可以工作。
我做错什么了吗?
提前致谢。
继续@zaph的注释中开始的列表:
Cipher.getInstance("RSA/ECB/PKCS1PADDING")
或Cipher.getInstance("RSA/ECB/NOPADDING")
。 您的错误是由数字5引起的。由于不能保证您的输入文件是117字节的精确倍数,因此最后一个块可能少于117字节。 但是,您随后将加密整个117字节的块,其中的尾随字节就是上一次读取后剩下的字节。 因此,解密后的文件将是117的倍数,并且将匹配原始长度,其尾随字节与上一个块的尾随字节相同。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.