我正在使用Java中的RSA算法进行加密/解密的简单程序。我按如下方式创建了一个密码对象:
//Create a Cipher object
Cipher rsaCipher = Cipher.getInstance("RSA/ECB/NoPadding");
我通过调用加密函数进行加密:
String cipher=encrypt(textByte, pair, rsaCipher);
System.out.println("The Encryption using RSA Algorithm : "+cipher);
解密为:
//Decryption
String plain=decrypt(Base64.decodeBase64(cipher),pair, rsaCipher);
System.out.println("The Decryption using RSA Algorithm : "+plain);
当我显示输出时,解密输出在原始文本之前返回一个长空格:
但是,当我编辑用于创建Cipher对象的代码时: //创建一个Cipher对象 密码rsaCipher = Cipher.getInstance(“RSA”);
即,删除了操作模式和填充参数,问题得到解决,输出变为:
问题出在哪里。在第一种情况下(当空间出现时),我指定了NoPadding?为什么空格出现在解密的消息中?即使我使用填充,我希望这不应该发生。
修改 这是加密和解密方法:
public static String encrypt(byte[] textBytes, KeyPair pair, Cipher rsaCipher) throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException
{
//get the public key
PublicKey pk=pair.getPublic();
//Initialize the cipher for encryption. Use the public key.
rsaCipher.init(Cipher.ENCRYPT_MODE, pk);
//Perform the encryption using doFinal
byte[] encByte = rsaCipher.doFinal(textBytes);
// converts to base64 for easier display.
byte[] base64Cipher = Base64.encodeBase64(encByte);
return new String(base64Cipher);
}//end encrypt
public static String decrypt(byte[] cipherBytes, KeyPair pair, Cipher rsaCipher) throws IllegalBlockSizeException, BadPaddingException, InvalidKeyException, NoSuchAlgorithmException, NoSuchPaddingException
{
//get the public key
PrivateKey pvk=pair.getPrivate();
//Create a Cipher object
//Cipher rsaCipher = Cipher.getInstance("RSA/ECB/NoPadding");
//Initialize the cipher for encryption. Use the public key.
rsaCipher.init(Cipher.DECRYPT_MODE, pvk);
//Perform the encryption using doFinal
byte[] decByte = rsaCipher.doFinal(cipherBytes);
return new String(decByte);
}//end decrypt
答案 0 :(得分:5)
你的问题确实与填充有关。实际上,某些填充(PKCS#1 1.5或OAEP填充)是安全RSA功能所必需的。此外,需要找到加密纯文本的开头和结尾。
RSA的模幂运算使用大整数执行。然后将这些操作的结果表示为八位字符串。这些八位字节串基本上是大端,无符号,整数的固定长度表示。这些整数用00
个值填充(这在RSA标准中称为I2OS原语)。所以你看到的是模幂运算的结果,00
填充仍然存在。
长话短说,总是使用填充方案。如今,OAEP将更为可取。将其与混合加密方案一起使用,或使用更高级别的容器格式,如CMS或PGP。
答案 1 :(得分:0)
RSA的模幂运算使用大整数执行。然后将这些操作的结果表示为八位字符串。这些八位字节串基本上是大端,无符号,整数的固定长度表示。这些整数用00值字节填充(这在RSA标准中称为I2OS原语)。所以你看到的是模幂运算的结果,00填充仍然存在。
答案 2 :(得分:0)
//This is a complete encryption and decryption module using
//Algorithm: JWEAlgorithm.RSA_OAEP_256
//Encryption Method: A128CBC_HS256
public static String encrypt(String text) throws Exception {
// Set the plain text
Payload payload = new Payload(text);
// Create the header
JWEHeader header = new JWEHeader(JWEAlgorithm.RSA_OAEP_256, EncryptionMethod.A128CBC_HS256);
// Create the JWE object and encrypt it
JWEObject jweObject = new JWEObject(header, payload);
jweObject.encrypt(new RSAEncrypter(getPublicKey()));
// Serialise to compact JOSE form...
String jweString = jweObject.serialize();
LOG.info("Generated Encrypted Key : {}", jweString);
return jweString;
}
public static String decrypt(String text) throws Exception {
// Parse into JWE object...
JWEObject jweObject = JWEObject.parse(text);
jweObject.decrypt(new RSADecrypter(getPrivateKey()));
// Get the plain text
Payload payload = jweObject.getPayload();
System.out.println(payload.toString());
return payload.toString();
}
private static RSAPublicKey getPublicKey() throws Exception {
String filename = "/home/vaibhav/Setups/cert/pub.der";
File f = new File(filename);
FileInputStream fis = new FileInputStream(f);
DataInputStream dis = new DataInputStream(fis);
byte[] keyBytes = new byte[(int)f.length()];
dis.readFully(keyBytes);
dis.close();
X509EncodedKeySpec spec = new X509EncodedKeySpec(keyBytes);
KeyFactory kf = KeyFactory.getInstance("RSA");
return (RSAPublicKey) kf.generatePublic(spec);
}
private static RSAPrivateKey getPrivateKey() throws Exception {
String filename = "/home/vaibhav/Setups/cert/private.pkcs8";
File f = new File(filename);
FileInputStream fis = new FileInputStream(f);
DataInputStream dis = new DataInputStream(fis);
byte[] keyBytes = new byte[(int)f.length()];
dis.readFully(keyBytes);
dis.close();
PKCS8EncodedKeySpec spec1 = new PKCS8EncodedKeySpec(keyBytes);
KeyFactory kf = KeyFactory.getInstance("RSA");
return (RSAPrivateKey) kf.generatePrivate(spec1);
}
答案 3 :(得分:-2)
希望这有帮助! :)
import java.util.*;
import java.math.*;
class RSA
{
public static void main(String args[])
{
BigInteger one, p, q, E, D, n,P,Q;
Scanner s = new Scanner(System.in);
Scanner t = new Scanner(System.in);
System.out.println("Enter A's prime number!");
p = s.nextBigInteger();
System.out.println("Enter B's prime number!");
q = s.nextBigInteger();
n = p.multiply(q);
P = p.subtract(BigInteger.ONE);
Q = q.subtract(BigInteger.ONE);
int x = 0;
do
{
System.out.println("Enter Public key ");
E =s.nextBigInteger();
if(((P.gcd(E)).equals(BigInteger.ONE))&&((Q.gcd(E)).equals(BigInteger.ONE)))
{x++;}
}while(x==0);
for(int i = 1;;i++)
{
D=new BigInteger(String.valueOf(i));
if(((D.multiply(E)).mod(P.multiply(Q))).equals(BigInteger.ONE))
break;
}
System.out.println("Enter Plain text!");
String in = "", out ="", text = t.nextLine();
for(int i = 0;i < text.length();i++){
BigInteger T = new BigInteger(String.valueOf((int)(text.charAt(i)))), O, TF;
O = T.modPow(E,n);
out += (char)O.intValue();
TF = O.modPow(D,n);
in += (char)TF.intValue();
}
System.out.println("Encrypted text : " + out);
System.out.println("Decrypted text : "+ in);
}
}