如何将android PublicKey转换为字符串并返回?

时间:2018-03-17 23:56:54

标签: android rsa public-key-encryption android-keystore

我正在尝试创建一个可以加密用户消息的应用。用户公钥需要作为字符串发布到服务器。我正在生成Android KyeStore PublicKey:

    public static PublicKey getOrCreatePublicKey(String alias) throws GeneralSecurityException, IOException {

    KeyStore keyStore = KeyStore.getInstance(ANDROID_PROVIDER);
    keyStore.load(null);
    if (!keyStore.containsAlias(alias) || keyStore.getCertificate(alias) == null) {

        KeyGenParameterSpec spec = new KeyGenParameterSpec.Builder(
                alias,
                KeyProperties.PURPOSE_DECRYPT | KeyProperties.PURPOSE_ENCRYPT)
                .setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_RSA_OAEP)
                .setDigests(KeyProperties.DIGEST_SHA256,
                        KeyProperties.DIGEST_SHA512)
                .build();
        KeyPairGenerator generator = KeyPairGenerator.getInstance(KeyProperties.KEY_ALGORITHM_RSA, ANDROID_PROVIDER);
        generator.initialize(spec);
        generator.generateKeyPair();
    }
    return keyStore.getCertificate(alias).getPublicKey();
}

然后我尝试将PublicKey转换为字符串并返回到PublicKey,如下所示:

public static PublicKey stringToPublicKey(String publStr)  {

    PublicKey publicKey = null;
    try {
        byte[] data = Base64.decode(publStr, Base64.DEFAULT);
        X509EncodedKeySpec spec = new X509EncodedKeySpec(data);
        KeyFactory fact = KeyFactory.getInstance("RSA");
        publicKey = fact.generatePublic(spec);
    } catch (GeneralSecurityException e) {
        e.printStackTrace();
    }
    return publicKey;
}


public static String publicKeyToString(PublicKey publ) {
    String publicKeyString = null;
    try {
        KeyFactory fact = KeyFactory.getInstance("RSA");
        X509EncodedKeySpec spec = fact.getKeySpec(publ,
                X509EncodedKeySpec.class);
        publicKeyString = Base64.encodeToString(spec.getEncoded(), Base64.DEFAULT);
    } catch (GeneralSecurityException e) {
        e.printStackTrace();
    }
    return publicKeyString;
}

然后我尝试使用公钥和私钥加密和解密用户消息。

如果我不转换公钥,加密工作正常。但是,如果我将公钥转换为字符串并返回公钥,则加密不再起作用。 我究竟做错了什么?谢谢。

   PublicKey publicKey1 = getOrCreatePublicKey("alias");
        String publicKeyStr = publicKeyToString(publicKey1);
        PublicKey publicKey2 = stringToPublicKey(publicKeyStr);

    //this one works            
        String message = encrypt(str, publicKey1);
        String decryptm = decrypt(message, privateKey);

    //this one doesn't work
    String message = encrypt(str, publicKey2);
        String decryptm = decrypt(message, privateKey);

2 个答案:

答案 0 :(得分:0)

我已经取代了

<强> KeyProperties.ENCRYPTION_PADDING_RSA_OAEP 同 的 KeyProperties.ENCRYPTION_PADDING_RSA_PKCS1

我也已经取代了

Cipher cipher = Cipher.getInstance(&#34; RSA / ECB / OAEPWithSHA-256AndMGF1Padding&#34;);

Cipher cipher = Cipher.getInstance(&#34; RSA / ECB / PKCS1Padding&#34;);

现在它有效。但我仍然不知道为什么它第一次不起作用。

答案 1 :(得分:0)

您的publicKeyToString函数是完全错误的,不应该将stringToPublicKey的所有步骤都在“反向”中再次执行。我是说,是的,但是虽然从字符串再次构造密钥确实需要执行所有步骤,但将PublicKey转换为String基本上只需要一行。

public static String publicKeyToString(PublicKey publ) {
    String publicKeyString = Base64.encodeToString(publ.getEncoded(), 2);
    return publicKeyString;
}

这应该输出一个与您的stringToPublicKey函数一起使用的String(对我来说看起来正确)。