当我尝试使用RSA加密和解密数据时,它的工作正常。
这里c是用户定义的类,它有rsaEncrypt和rsaDecrypt方法。
byte b[]=c.rsaEncrypt("voterpublickey.key",(""+randomnumber).getBytes(),"public")<br>
new String(c.rsaDecrypt("voterprivatekey.key",b,"private"));
但在这里我需要使用RSA进行E(priv(LA),E(Pub(VF),vnumber))加密。 但它在加密和解密时都会引发错误。
加密时
b=c.rsaEncrypt("vfpublickey.key",(vnumber+"").getBytes(),"public");
b=c.rsaEncrypt("laprivatekey.key",b,"private");
stacktrace:
javax.crypto.IllegalBlockSizeException: Data must not be longer than 245 bytes
at com.sun.crypto.provider.RSACipher.doFinal(RSACipher.java:344)
at com.sun.crypto.provider.RSACipher.engineDoFinal(RSACipher.java:389)
at javax.crypto.Cipher.doFinal(Cipher.java:2165)
at cli.rsaEncrypt(cli.java:79)
at LaSer.main(LaSer.java:108)
解密时
byte b[]=c.rsaDecrypt("lapublickey.key",b,"public");
new String(c.rsaDecrypt("vfprivatekey.key",b,"private"));
stacktrace:
javax.crypto.BadPaddingException: Decryption error
at sun.security.rsa.RSAPadding.unpadV15(RSAPadding.java:380)
at sun.security.rsa.RSAPadding.unpad(RSAPadding.java:291)
at com.sun.crypto.provider.RSACipher.doFinal(RSACipher.java:363)
at com.sun.crypto.provider.RSACipher.engineDoFinal(RSACipher.java:389)
at javax.crypto.Cipher.doFinal(Cipher.java:2165)
at cli.rsaDecrypt(cli.java:99)
at ConnectionWithLaser.run(VfSer.java:371)
我做错了什么。加密加密数据是对的吗?
有没有办法处理这种情况?
更新
PrivateKey readKeyFromFileDecrypt(String keyFileName) throws IOException {
InputStream in =
cli.class.getResourceAsStream(keyFileName);
ObjectInputStream oin =
new ObjectInputStream(new BufferedInputStream(in));
try {
BigInteger m = (BigInteger) oin.readObject();
BigInteger e = (BigInteger) oin.readObject();
RSAPrivateKeySpec keySpec = new RSAPrivateKeySpec(m, e);
KeyFactory fact = KeyFactory.getInstance("RSA");
PrivateKey priKey = fact.generatePrivate(keySpec);
return priKey;
} catch (Exception e) {
throw new RuntimeException("Spurious serialisation error", e);
} finally {
oin.close();
}
}
//similar function readKeyFromFileEncrypt
public byte[] rsaEncrypt(String keyFileName,byte[] data,String key)throws Exception {
if(key.equals("public")){
PublicKey pubKey = readKeyFromFileEncrypt(keyFileName);
Cipher cipher = Cipher.getInstance("RSA");
cipher.init(Cipher.ENCRYPT_MODE, pubKey);
}
else if(key.equals("private"))
{
PrivateKey priKey = readKeyFromFileDecrypt(keyFileName);
Cipher cipher = Cipher.getInstance("RSA");
cipher.init(Cipher.ENCRYPT_MODE, priKey);
}
byte[] cipherData = cipher.doFinal(data);
return cipherData;
}
public byte[] rsaDecrypt(String keyFileName,byte[] data,String key)throws Exception{
if(key.equals("public")){
PublicKey pubKey = readKeyFromFileEncrypt(keyFileName);
Cipher cipher = Cipher.getInstance("RSA");
cipher.init(Cipher.DECRYPT_MODE, pubKey);
}
else if(key.equals("private"))
{
PrivateKey priKey = readKeyFromFileDecrypt(keyFileName);
Cipher cipher = Cipher.getInstance("RSA");
cipher.init(Cipher.DECRYPT_MODE, priKey);
}
byte[] originalData = cipher.doFinal(data);
return originalData;
}
最后生成公钥和私钥
KeyPairGenerator kpg = KeyPairGenerator.getInstance("RSA");
kpg.initialize(2048);
KeyPair kp = kpg.genKeyPair();
Key publicKey = kp.getPublic();
Key privateKey = kp.getPrivate();
答案 0 :(得分:0)
基本上你的代码很好。
我使用以下代码复制了您的问题:
package foo;
import java.security.Key;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.SecureRandom;
import java.util.Arrays;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
public class FooTest
{
public static void main( String[] args ) throws Exception
{
KeyPairGenerator kpg = KeyPairGenerator.getInstance( "RSA" );
int keysize = 2048;
kpg.initialize( keysize );
KeyPair keys = kpg.genKeyPair();
SecureRandom rng = new SecureRandom();
byte[] data = new byte[keysize / 8 - 11];
rng.nextBytes( data );
// "encryption"
byte[] cipherText = encrypt( data, keys.getPublic() );
byte[] decrypted = decrypt( cipherText, keys.getPrivate() );
if ( !Arrays.equals( data, decrypted ) )
{
throw new IllegalStateException( "decrypted was not equal to message" );
}
// "signature"
cipherText = encrypt( data, keys.getPrivate() );
decrypted = decrypt( cipherText, keys.getPublic() );
if ( !Arrays.equals( data, decrypted ) )
{
throw new IllegalStateException( "decrypted was not equal to message" );
}
data = new byte[keysize / 8 - 10];
rng.nextBytes( data );
try
{
encrypt( data, keys.getPublic() );
}
catch ( IllegalBlockSizeException e )
{
System.err.println( "data size of " + data.length + " may not exceed " + (keysize / 8 - 11) );
}
}
static byte[] encrypt( byte[] data, Key key ) throws Exception
{
Cipher cipher = Cipher.getInstance( "RSA" );
cipher.init( Cipher.ENCRYPT_MODE, key );
return cipher.doFinal( data );
}
static byte[] decrypt( byte[] data, Key key ) throws Exception
{
Cipher cipher = Cipher.getInstance( "RSA" );
cipher.init( Cipher.DECRYPT_MODE, key );
return cipher.doFinal( data );
}
}
RFC 3447描述了为什么限制比实际密钥大小11个字节。