如何使用SubjectPublicKeyInfo加密数据?

时间:2014-12-17 03:33:02

标签: java encryption rsa bouncycastle

我是RSA的新手并且使用BC从公钥获取SubjectPublicKeyInfo。

String key = "-----BEGIN RSA PUBLIC KEY-----\n" +
             "........\n" +// Multiple lines here
             "-----END RSA PUBLIC KEY-----\n";

Security.addProvider(new BouncyCastleProvider());
PEMParser reader = new PEMParser(new StringReader(key));
SubjectPublicKeyInfo subjectPublicKeyInfo = (SubjectPublicKeyInfo) reader.readObject();

然后我想要加密数据。我发现有人使用RSAEngine来做这件事:

AsymmetricKeyParameter aKey = (RSAKeyParameters) PublicKeyFactory.createKey(subjectPublicKeyInfo);
AsymmetricBlockCipher engine = new RSAEngine();
engine.init(false, aKey);
byte[] dataEncrypted = engine.processBlock(data, 0, data.length);

运行这些代码后,我发现结果并不等于预期。 所以我想知道我的代码中是否有任何错误?

1 个答案:

答案 0 :(得分:0)

最后我找到了出路。

如果有人熟悉BouncyCastle,他可以指出我的低级错误。

首先,要在Engine函数中首先使用true init初始化BouncyCastle来加密数据。

其次,我的公钥是以' ----- BEGIN RSA PUBLIC KEY ----- '开头。它是 PKCS#1 格式的RSA公钥,应该使用padding来读取,但加密数据应该有RSAEngine。所以,我不应该直接使用PKCS1Encoding,而是使用Security.addProvider(new BouncyCastleProvider()); PEMParser reader = new PEMParser(new StringReader(key)); SubjectPublicKeyInfo subjectPublicKeyInfo = (SubjectPublicKeyInfo) reader.readObject(); RSAKeyParameters rsaKeyParameters = (RSAKeyParameters) PublicKeyFactory.createKey(subjectPublicKeyInfo); PKCS1Encoding engine = new PKCS1Encoding(new RSAEngine()); engine.init(true, rsaKeyParameters); return engine.processBlock(data, 0, data.length);

最后,发布我的加密代码并解密代码:

加密:

public static byte[] decryptByPublicKey(String data, String key) throws Exception {
    byte[] rawData = Base64.decode(data);
    Security.addProvider(new BouncyCastleProvider());
    PEMParser reader = new PEMParser(new StringReader(key));
    PEMKeyPair pemKeyPair = (PEMKeyPair) reader.readObject();
    SubjectPublicKeyInfo publicKeyInfo = pemKeyPair.getPublicKeyInfo();
    PrivateKeyInfo privateKeyInfo = pemKeyPair.getPrivateKeyInfo();
    RSAKeyParameters rsaKeyParameters = (RSAKeyParameters)     
    PrivateKeyFactory.createKey(privateKeyInfo);
    PKCS1Encoding engine = new PKCS1Encoding(new RSAEngine());
    engine.init(false, rsaKeyParameters);
    return engine.processBlock(rawData, 0, rawData.length);
}

解密:

    Security.addProvider(new BouncyCastleProvider());
    PEMParser reader = new PEMParser(new StringReader(key));
    PemObject obj = reader.readPemObject();
    org.bouncycastle.asn1.pkcs.RSAPublicKey rsaPublicKey = org.bouncycastle.asn1.pkcs.RSAPublicKey.getInstance(obj.getContent());
    BigInteger modulus = rsaPublicKey.getModulus();
    BigInteger publicExponent = rsaPublicKey.getPublicExponent();

    KeyFactory keyFactory = KeyFactory.getInstance("RSA", "BC");
    RSAPublicKeySpec pubKeySpec = new RSAPublicKeySpec(modulus, publicExponent);
    PublicKey pubKey = keyFactory.generatePublic(pubKeySpec);

    Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding", "BC");//This line should use right padding.For PKCS#1 format RSA key , it should be this.
    cipher.init(Cipher.ENCRYPT_MODE, pubKey);
    return cipher.doFinal(data);

对于加密,您可以使用模数和公共指数来​​创建JDK支持的密钥:

{{1}}

另请参阅:Basic RSA example.