我是加密场景的新手。我试图将DecryptStringTest
方法从文章Code Project - Cryptography with certificates移植到java。
我从RSA xml格式加载私钥(通过c#生成)。我将这些值放在包含模数,指数,p,q,dp,dq,inverseQ和d的RsaKeyValue类中。
每次我运行它decrypt()
,然后传递加密的String,我都会遇到这个异常:
BadPaddingException:消息大于模数。
密钥大小为1024.我不明白为什么当使用在c#中使用私钥生成的公钥加密字符串时,它首先给出了我的错误。消息怎么可能比模数大?也许我没有错误地加载我的RSA密钥?
任何见解都会很棒。谢谢!
PS我将清理我的代码。对不起,如果看起来很难看。我只想要这件事。
到目前为止,我的代码看起来像这样。
import java.io.ByteArrayOutputStream;
import java.io.IOException;
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.interfaces.RSAPrivateKey;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.RSAPrivateCrtKeySpec;
import java.security.spec.RSAPrivateKeySpec;
import java.security.spec.RSAPublicKeySpec;
import java.util.ArrayList;
import java.util.List;
import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import org.apache.commons.codec.binary.Base64;
public class RsaKeys {
private final String rsaDecAlgorithm = "RSA";
private static KeyFactory kf;
private static Cipher cipher;
public PublicKey publicKey;
public PrivateKey privateKey;
private RsaKeyValue rsaKeyVal = new RsaKeyValue();
public RsaKeys(String path) {
this.rsaKeyVal = new RsaKeyValue(path);
this.privateKey = makePrivateKey();
//this.privateKey = makePrivateKeyTwo();
this.publicKey = makePublicKey();
}
public String encryptString(byte[] input) {
try {
cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
cipher.init(Cipher.ENCRYPT_MODE, publicKey);
byte[] ret = cipher.doFinal(input);
return Base64.encodeBase64String(ret);
} catch (InvalidKeyException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalBlockSizeException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (BadPaddingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (NoSuchAlgorithmException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (NoSuchPaddingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
public String decrypt(String encryptedString) {
try {
cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
cipher.init(Cipher.DECRYPT_MODE, privateKey);
} catch (InvalidKeyException | NoSuchAlgorithmException | NoSuchPaddingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
int base64BlockSize = (this.rsaKeyVal.getBitStrength() / 8) % 3 != 0
? (((this.rsaKeyVal.getBitStrength() / 8) / 3) * 4) + 4
: (((this.rsaKeyVal.getBitStrength() / 8)) / 3) * 4;
int iterations = encryptedString.length() / base64BlockSize;
List<byte[]> temp = new ArrayList<byte[]>();
/**/
System.out.println("base64BlockSize: " + base64BlockSize);
System.out.println("Iterations: " + iterations);
/**/
for (int i = 0; i < iterations; i++) {
try {
byte[] bytesArray = Base64
.decodeBase64(encryptedString.substring(base64BlockSize * i, base64BlockSize));
/**/
System.out.println("Byte Array Encrypted String Length: " + bytesArray.length);
System.out.println("Encoded Byte Array Encrypted String: " + Base64.encodeBase64String((bytesArray)));
/**/
temp.add(cipher.doFinal(bytesArray));
} catch (IllegalBlockSizeException e) {
e.printStackTrace();
} catch (BadPaddingException e) {
e.printStackTrace();
}
}
ByteArrayOutputStream bStr = new ByteArrayOutputStream();
byte[] retBal = null;
try {
temp.stream().forEach(x -> {
try {
bStr.write(x);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
});
retBal = bStr.toByteArray();
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
bStr.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
return Base64.encodeBase64String(retBal).toString();
}
public String getPrivateKeyModulus() {
RSAPrivateKey temp = (RSAPrivateKey) privateKey;
return "Modulus: " + temp.getModulus();
}
private PublicKey makePublicKey() {
try {
byte[] modBytes = Base64.decodeBase64(this.rsaKeyVal.getModulus());
byte[] expBytes = Base64.decodeBase64(this.rsaKeyVal.getExponent());
kf = KeyFactory.getInstance(rsaDecAlgorithm);
BigInteger mod = new BigInteger(1, modBytes);
BigInteger exp = new BigInteger(1, expBytes);
RSAPublicKeySpec pubSpec = new RSAPublicKeySpec(mod, exp);
PublicKey pubKey = kf.generatePublic(pubSpec);
return pubKey;
} catch (InvalidKeySpecException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (NoSuchAlgorithmException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
private PrivateKey makePrivateKey() {
try {
byte[] modBytes = Base64.decodeBase64(this.rsaKeyVal.getModulus());
byte[] dBytes = Base64.decodeBase64(this.rsaKeyVal.getD());
kf = KeyFactory.getInstance(rsaDecAlgorithm);
BigInteger mod = new BigInteger(1, modBytes);
BigInteger d = new BigInteger(1, dBytes);
RSAPrivateKeySpec privSpec = new RSAPrivateKeySpec(mod, d);
PrivateKey pKey = kf.generatePrivate(privSpec);
return pKey;
} catch (InvalidKeySpecException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (NoSuchAlgorithmException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
private PrivateKey makePrivateKeyTwo() {
byte[] modBytes = Base64.decodeBase64(this.rsaKeyVal.getModulus());
byte[] expBytes = Base64.decodeBase64(this.rsaKeyVal.getExponent());
byte[] dBytes = Base64.decodeBase64(this.rsaKeyVal.getD());
byte[] pBytes = Base64.decodeBase64(this.rsaKeyVal.getP());
byte[] qBytes = Base64.decodeBase64(this.rsaKeyVal.getQ());
byte[] dpBytes = Base64.decodeBase64(this.rsaKeyVal.getDp());
byte[] dqBytes = Base64.decodeBase64(this.rsaKeyVal.getDq());
byte[] inverseQBytes = Base64.decodeBase64(this.rsaKeyVal.getInverseQ());
BigInteger mod = new BigInteger(1, modBytes);
BigInteger exp = new BigInteger(1, expBytes);
BigInteger d = new BigInteger(1, dBytes);
BigInteger p = new BigInteger(1, pBytes);
BigInteger q = new BigInteger(1, qBytes);
BigInteger dp = new BigInteger(1, dpBytes);
BigInteger dq = new BigInteger(1, dqBytes);
BigInteger inverseQ = new BigInteger(1, inverseQBytes);
RSAPrivateCrtKeySpec keySpec =
new RSAPrivateCrtKeySpec(
mod,
exp,
d,
p,
q,
dp,
dq,
inverseQ
);
try {
kf = KeyFactory.getInstance(rsaDecAlgorithm);
PrivateKey key = kf.generatePrivate(keySpec);
return key;
} catch (NoSuchAlgorithmException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InvalidKeySpecException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
}
异常堆栈:
javax.crypto.BadPaddingException:消息大于模数 at sun.security.rsa.RSACore.parseMsg(RSACore.java:214) at sun.security.rsa.RSACore.priCrypt(RSACore.java:144) 在sun.security.rsa.RSACore.rsa(RSACore.java:124) 在com.sun.crypto.provider.RSACipher.doFinal(RSACipher.java:362) 在com.sun.crypto.provider.RSACipher.engineDoFinal(RSACipher.java:389) 在javax.crypto.Cipher.doFinal(Cipher.java:2165) 在Entities.RsaKeys.decrypt(RsaKeys.java:72) 在DecryptTest.getRsaPrivateKey(DecryptTest.java:36) 在DecryptTest.testOne(DecryptTest.java:26) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:498) 在org.junit.runners.model.FrameworkMethod $ 1.runReflectiveCall(FrameworkMethod.java:50) 在org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12) 在org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47) 在org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17) 在org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26) 在org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325) 在org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78) 在org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57) 在org.junit.runners.ParentRunner $ 3.run(ParentRunner.java:290) 在org.junit.runners.ParentRunner $ 1.schedule(ParentRunner.java:71) 在org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288) 在org.junit.runners.ParentRunner.access $ 000(ParentRunner.java:58) 在org.junit.runners.ParentRunner $ 2.evaluate(ParentRunner.java:268) 在org.junit.runners.ParentRunner.run(ParentRunner.java:363) 在org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:86) 在org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38) 在org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:459) 在org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:678) 在org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:382) 在org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:192)
更改了代码。增加了加密能力。现在可以打印解密的字符串(如果使用代码加密)。还添加了另一种制作私钥的方法。
一直在玩它。我可以成功加密和解密随机字符串。