我正在加密java中的文件,并将加密的文件和私钥发送到Android设备。但是在解密Android中的文件时,它会给pad块损坏错误。 顺便说一下,相同的解密代码可以在PC上运行
以下是加密:
public void encrypt(File inf, File outf, File publicKey, int userId, int resourceId) throws ArServerConnectionException {
// ENCRYPTION BEGIN
try {
pkCipher = Cipher.getInstance("RSA");
} catch (NoSuchAlgorithmException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (NoSuchPaddingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
// create AES shared key cipher
try {
aesCipher = Cipher.getInstance("AES");
} catch (NoSuchAlgorithmException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (NoSuchPaddingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try {
makeKey();
} catch (NoSuchAlgorithmException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
// File operation
try {
saveKey(new File(System.getProperty("user.home") + "/" + userId
+ "/keyfile"), publicKey);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (GeneralSecurityException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
// File operation
try {
encryptFiles(inf, outf);
} catch (InvalidKeyException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
// /ENCRYPTION END
}
public void saveKey(File out, File publicKeyFile) throws IOException,
GeneralSecurityException {
// read public key to be used to encrypt the AES key
byte[] encodedKey = new byte[(int) publicKeyFile.length()];
new FileInputStream(publicKeyFile).read(encodedKey);
// create public key
X509EncodedKeySpec publicKeySpec = new X509EncodedKeySpec(encodedKey);
KeyFactory kf = KeyFactory.getInstance("RSA");
PublicKey pk = kf.generatePublic(publicKeySpec);
// write AES key
pkCipher.init(Cipher.ENCRYPT_MODE, pk);
CipherOutputStream os = new CipherOutputStream(
new FileOutputStream(out), pkCipher);
os.write(aesKey);
os.close();
}
public void makeKey() throws NoSuchAlgorithmException {
KeyGenerator kgen = KeyGenerator.getInstance("AES");
kgen.init(AES_Key_Size);
SecretKey key = kgen.generateKey();
aesKey = key.getEncoded();
aeskeySpec = new SecretKeySpec(aesKey, "AES");
}
这是解密部分:
public class FileDecrypt {
public static final int AES_Key_Size = 256;
Cipher pkCipher, aesCipher;
byte[] aesKey;
SecretKeySpec aeskeySpec;
private String pubKeyPath=null;
private String prvKeyPath=null;
private String keyFilePath=null;
private String encFilePath=null;
private String unencFilePath=null;
public String getEncFilePath() {
return encFilePath;
}
public void setEncFilePath(String encFilePath) {
this.encFilePath = encFilePath;
}
public String getUnencFilePath() {
return unencFilePath;
}
public void setUnencFilePath(String unencFilePath) {
this.unencFilePath = unencFilePath;
}
public String getPubKeyPath() {
return pubKeyPath;
}
public void setPubKeyPath(String pubKeyPath) {
this.pubKeyPath = pubKeyPath;
}
public String getPrvKeyPath() {
return prvKeyPath;
}
public void setPrvKeyPath(String prvKeyPath) {
this.prvKeyPath = prvKeyPath;
}
public String getKeyFilePath() {
return keyFilePath;
}
public void setKeyFilePath(String keyFilePath) {
this.keyFilePath = keyFilePath;
}
public void decrypt() {
Log.i("DECRYPT","**************************************************DECRYPT&*******************");
Log.i("encFilePath",encFilePath);
Log.i("pubKeyPath",pubKeyPath);
Log.i("prvKeyPath",prvKeyPath);
Log.i("keyFilePath",keyFilePath);
Log.i("unencFilePath",unencFilePath);
Log.i("DECRYPT","********************************************DECRYPT&*******************");
try {
pkCipher = Cipher.getInstance("RSA");
} catch (NoSuchAlgorithmException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (NoSuchPaddingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try {
aesCipher = Cipher.getInstance("AES");
} catch (NoSuchAlgorithmException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (NoSuchPaddingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
//DECRYPTION BEGIN
File pkf=new File(pubKeyPath);
byte[] encodedKey = new byte[(int) pkf.length()];
try {
new FileInputStream(pkf).read(encodedKey);
// create public key
X509EncodedKeySpec publicKeySpec = new X509EncodedKeySpec(encodedKey);
KeyFactory kf = KeyFactory.getInstance("RSA");
PublicKey pk = kf.generatePublic(publicKeySpec);
// write AES key
pkCipher.init(Cipher.ENCRYPT_MODE, pk);
} catch (FileNotFoundException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
} catch (NoSuchAlgorithmException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InvalidKeyException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InvalidKeySpecException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try {
loadKey(new File(keyFilePath), new File(prvKeyPath));
} catch (GeneralSecurityException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try {
decrypt(new File(encFilePath), new File(unencFilePath));
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
//DECRYPTION END
}
/**
* Decrypts an AES key from a file using an RSA private key
*/
public void loadKey(File in, File privateKeyFile)
throws GeneralSecurityException, IOException {
// read private key to be used to decrypt the AES key
byte[] encodedKey = new byte[(int) privateKeyFile.length()];
new FileInputStream(privateKeyFile).read(encodedKey);
// create private key
PKCS8EncodedKeySpec privateKeySpec = new PKCS8EncodedKeySpec(encodedKey);
KeyFactory kf = KeyFactory.getInstance("RSA");
PrivateKey pk = kf.generatePrivate(privateKeySpec);
// read AES key
pkCipher.init(Cipher.DECRYPT_MODE, pk);
aesKey = new byte[AES_Key_Size / 8];
CipherInputStream is = new CipherInputStream(new FileInputStream(in),
pkCipher);
is.read(aesKey);
aeskeySpec = new SecretKeySpec(aesKey, "AES");
}
/**
* Decrypts and then copies the contents of a given file.
*/
public void decrypt(File in, File out) throws IOException
{
try {
aesCipher.init(Cipher.DECRYPT_MODE, aeskeySpec);
} catch (InvalidKeyException e) {
Log.i("EXCEPTION","INVALID KEY EXCEPTION");
e.printStackTrace();
}
CipherInputStream is = new CipherInputStream(new FileInputStream(in),
aesCipher);
FileOutputStream os = new FileOutputStream(out);
copy(is, os);
is.close();
os.close();
}
/**
* Copies a stream.
*/
private void copy(InputStream is, OutputStream os) throws IOException {
int i;
byte[] b = new byte[2048];
while ((i = is.read(b)) != -1) {
os.write(b, 0, i);
}
}
}
答案 0 :(得分:4)
我们也遇到了同样的问题,它只在android端进行加密部分(使用android SDK),然后在设备上解密时解决了。没有找到该问题的其他正确理由..
答案 1 :(得分:0)
最可能的原因是您用于将文件发送到设备的代码不正确。也许是截断,填充或以其他方式破坏数据,因此它无法正确解密。尝试使用静态文件进行测试,看看是否可以隔离问题。
答案 2 :(得分:0)
您正在加密文件的PC正在使用不同的安全提供程序(主要是SunJCE),而Android使用安全提供程序“BC”(4.2之前的Bouncy Castle,4.2之后的AndroidOpenssl)来解密文件。因此解密在Android设备上不成功。请使用此地点Bouncy castle jar download对应您的PC类型的充气城堡罐。
使用PC中的java代码中的提供程序“BC”进行加密。
Cipher cipher = Cipher.getInstance("AES", "BC");
Decyption在android方面可以正常工作:)