Java 在android中使用rsa解密时获取垃圾字符串
我使用netbeans编写了一个程序来加密一个字符串,它可以像java应用程序一样完美地运行。它解密文件中存储的文本。后来,我将文件传输到我的android程序,解密失败(android应用程序无法按预期工作)。它是在给垃圾字符串。即预加密字符串和后解密字符串不相同。代码如下,请查看并帮助我- RSABase.javaJava 在android中使用rsa解密时获取垃圾字符串,java,android,encryption,cryptography,rsa,Java,Android,Encryption,Cryptography,Rsa,我使用netbeans编写了一个程序来加密一个字符串,它可以像java应用程序一样完美地运行。它解密文件中存储的文本。后来,我将文件传输到我的android程序,解密失败(android应用程序无法按预期工作)。它是在给垃圾字符串。即预加密字符串和后解密字符串不相同。代码如下,请查看并帮助我- RSABase.java public class RSABase { public static byte[] hexToByte(String hex) {
public class RSABase {
public static byte[] hexToByte(String hex)
{
byte bts[] = new byte[hex.length() / 2];
for(int i = 0; i < bts.length; i++){
bts[i] = (byte)Integer.parseInt(hex.substring(2 * i, 2 * i + 2), 16);
}
return bts;
}
public static String toHexString(byte bytes[])
{
StringBuffer retString = new StringBuffer();
for(int i = 0; i < bytes.length; i++)
retString.append(Integer.toHexString(256 + (bytes[i] & 0xff)).substring(1));
return retString.toString();
}
}
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.math.BigInteger;
import java.security.InvalidKeyException;
import java.security.KeyFactory;
import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.spec.RSAPrivateKeySpec;
import java.security.spec.RSAPublicKeySpec;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import android.os.Environment;
/**
*
* @author Test01
*/
public class Decryptor extends RSABase {
private PrivateKey key;
private String text;
public Decryptor(String text) {
this.text = text;
try {
key=readPrivateKeyFromFile(Environment.getExternalStorageDirectory()+"/private.key");
} catch (IOException ex) {
Logger.getLogger(Decryptor.class.getName()).log(Level.SEVERE, null, ex);
}
}
private PublicKey readPublicKeyFromFile(String fileName) throws IOException {
FileInputStream fis = null;
ObjectInputStream ois = null;
try {
fis = new FileInputStream(new File(fileName));
ois = new ObjectInputStream(fis);
BigInteger modulus = (BigInteger) ois.readObject();
BigInteger exponent = (BigInteger) ois.readObject();
//Get Public Key
RSAPublicKeySpec rsaPublicKeySpec = new RSAPublicKeySpec(modulus, exponent);
KeyFactory fact = KeyFactory.getInstance("RSA");
PublicKey publicKey = fact.generatePublic(rsaPublicKeySpec);
return publicKey;
} catch (Exception e) {
e.printStackTrace();
} finally {
if (ois != null) {
ois.close();
if (fis != null) {
fis.close();
}
}
}
return null;
}
private PrivateKey readPrivateKeyFromFile(String fileName) throws IOException {
FileInputStream fis = null;
ObjectInputStream ois = null;
try {
fis = new FileInputStream(new File(fileName));
ois = new ObjectInputStream(fis);
BigInteger modulus = (BigInteger) ois.readObject();
BigInteger exponent = (BigInteger) ois.readObject();
//Get Private Key
RSAPrivateKeySpec rsaPrivateKeySpec = new RSAPrivateKeySpec(modulus, exponent);
KeyFactory fact = KeyFactory.getInstance("RSA");
key = fact.generatePrivate(rsaPrivateKeySpec);
return key;
} catch (Exception e) {
e.printStackTrace();
} finally {
if (ois != null) {
ois.close();
if (fis != null) {
fis.close();
}
}
}
return null;
}
public String decrypt(){
byte[] decrypted=null;
byte[] decryptable=hexToByte(text);
String dec=null;
try {
Cipher cipher=Cipher.getInstance("RSA");
cipher.init(Cipher.DECRYPT_MODE, key);
decrypted=cipher.doFinal(decryptable);
} catch (NoSuchAlgorithmException ex) {
Logger.getLogger(Decryptor.class.getName()).log(Level.SEVERE, null, ex);
} catch (NoSuchPaddingException ex) {
Logger.getLogger(Decryptor.class.getName()).log(Level.SEVERE, null, ex);
} catch (InvalidKeyException ex) {
Logger.getLogger(Decryptor.class.getName()).log(Level.SEVERE, null, ex);
} catch (IllegalBlockSizeException ex) {
Logger.getLogger(Decryptor.class.getName()).log(Level.SEVERE, null, ex);
} catch (BadPaddingException ex) {
Logger.getLogger(Decryptor.class.getName()).log(Level.SEVERE, null, ex);
}
dec = new String(decrypted);
return dec;
}
}
Decryptor.java
public class RSABase {
public static byte[] hexToByte(String hex)
{
byte bts[] = new byte[hex.length() / 2];
for(int i = 0; i < bts.length; i++){
bts[i] = (byte)Integer.parseInt(hex.substring(2 * i, 2 * i + 2), 16);
}
return bts;
}
public static String toHexString(byte bytes[])
{
StringBuffer retString = new StringBuffer();
for(int i = 0; i < bytes.length; i++)
retString.append(Integer.toHexString(256 + (bytes[i] & 0xff)).substring(1));
return retString.toString();
}
}
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.math.BigInteger;
import java.security.InvalidKeyException;
import java.security.KeyFactory;
import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.spec.RSAPrivateKeySpec;
import java.security.spec.RSAPublicKeySpec;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import android.os.Environment;
/**
*
* @author Test01
*/
public class Decryptor extends RSABase {
private PrivateKey key;
private String text;
public Decryptor(String text) {
this.text = text;
try {
key=readPrivateKeyFromFile(Environment.getExternalStorageDirectory()+"/private.key");
} catch (IOException ex) {
Logger.getLogger(Decryptor.class.getName()).log(Level.SEVERE, null, ex);
}
}
private PublicKey readPublicKeyFromFile(String fileName) throws IOException {
FileInputStream fis = null;
ObjectInputStream ois = null;
try {
fis = new FileInputStream(new File(fileName));
ois = new ObjectInputStream(fis);
BigInteger modulus = (BigInteger) ois.readObject();
BigInteger exponent = (BigInteger) ois.readObject();
//Get Public Key
RSAPublicKeySpec rsaPublicKeySpec = new RSAPublicKeySpec(modulus, exponent);
KeyFactory fact = KeyFactory.getInstance("RSA");
PublicKey publicKey = fact.generatePublic(rsaPublicKeySpec);
return publicKey;
} catch (Exception e) {
e.printStackTrace();
} finally {
if (ois != null) {
ois.close();
if (fis != null) {
fis.close();
}
}
}
return null;
}
private PrivateKey readPrivateKeyFromFile(String fileName) throws IOException {
FileInputStream fis = null;
ObjectInputStream ois = null;
try {
fis = new FileInputStream(new File(fileName));
ois = new ObjectInputStream(fis);
BigInteger modulus = (BigInteger) ois.readObject();
BigInteger exponent = (BigInteger) ois.readObject();
//Get Private Key
RSAPrivateKeySpec rsaPrivateKeySpec = new RSAPrivateKeySpec(modulus, exponent);
KeyFactory fact = KeyFactory.getInstance("RSA");
key = fact.generatePrivate(rsaPrivateKeySpec);
return key;
} catch (Exception e) {
e.printStackTrace();
} finally {
if (ois != null) {
ois.close();
if (fis != null) {
fis.close();
}
}
}
return null;
}
public String decrypt(){
byte[] decrypted=null;
byte[] decryptable=hexToByte(text);
String dec=null;
try {
Cipher cipher=Cipher.getInstance("RSA");
cipher.init(Cipher.DECRYPT_MODE, key);
decrypted=cipher.doFinal(decryptable);
} catch (NoSuchAlgorithmException ex) {
Logger.getLogger(Decryptor.class.getName()).log(Level.SEVERE, null, ex);
} catch (NoSuchPaddingException ex) {
Logger.getLogger(Decryptor.class.getName()).log(Level.SEVERE, null, ex);
} catch (InvalidKeyException ex) {
Logger.getLogger(Decryptor.class.getName()).log(Level.SEVERE, null, ex);
} catch (IllegalBlockSizeException ex) {
Logger.getLogger(Decryptor.class.getName()).log(Level.SEVERE, null, ex);
} catch (BadPaddingException ex) {
Logger.getLogger(Decryptor.class.getName()).log(Level.SEVERE, null, ex);
}
dec = new String(decrypted);
return dec;
}
}
用于解密的代码:
Decryptor dec=new Decryptor(tokens[1]);//string loaded from file.
password=dec.decrypt();
它正在从文件中正确加载字符串。
感谢您的帮助。提前感谢。您是在Java本地运行代码,还是将密钥和/或密文从Java SE传输到Android?请注意,我认为您已经很好地选择了标识符,但是类设计和异常处理还有一些需要改进的地方(例如,只使用静态方法扩展类是一种已知的反模式)。在se中创建了密钥并在android中使用。是的,我同意您仅使用静态方法扩展类。没有必要扩展这样的类。您可能需要检查Java SE和Android之间是否存在编码/解码问题。如果您可以创建这些关键点,它们可能是正常的(当然,除非您切换了它们)。例如,
dec=新字符串(已解密)代码>未指定编码。我尝试了UTF-8,但仍然得到相同的垃圾。虽然原始字符串位于垃圾的末尾。