1

我用带有填充SwiftyRSA的公钥加密字符串。PKCS1不幸的是,BadPadding: Encryption Error当我在 Java 中解密我的加密字符串时,我发现了。到目前为止,我发现 Java 用于Mode加密/解密字符串,但Mode在 iOS/Swift 中没有。请让我知道我应该使用哪种算法在 Swift 和 Java 之间加密/解密。

这是用于加密/解密的公钥和私钥

https://github.com/ppshein/Encrypt-Decrypt

快速加密

let publicKey = try PublicKey(pemNamed: "public")
let clear = try ClearMessage(string: inString, using: .utf8)
let encrypted = try clear.encrypted(with: publicKey, padding: .init(rawValue: 0))
let base64 = encrypted.data.base64EncodedString()

Java解密

public class CryptographyUsingKeystore {
    private static final String ALGORITHM = "RSA";
    public static byte[] encrypt(PublicKey publicKey, byte[] inputData)
            throws Exception {
        Cipher cipher = Cipher.getInstance(ALGORITHM);
        cipher.init(Cipher.PUBLIC_KEY, publicKey);
        byte[] encryptedBytes = cipher.doFinal(inputData);
        return encryptedBytes;
    }
    public static byte[] decrypt(PrivateKey privateKey, byte[] inputData)
            throws Exception {
        Cipher cipher = Cipher.getInstance(ALGORITHM);
        cipher.init(Cipher.PRIVATE_KEY, privateKey);
        byte[] decryptedBytes = cipher.doFinal(inputData);
        return decryptedBytes;
    }
    public static void main(String[] args) throws Exception {
        KeyProvider keyProvider = new KeyProvider();

        PublicKey publicKey = myKey.getPemPublicKey();
        //PrivateKey privateKey = (PrivateKey) keyProvider.getPrivateKey();

        byte[] encryptedData = encrypt(publicKey,
                "Hello".getBytes());

        System.out.println("Encrypted Key.... ");
        System.out.println(new String(Base64.getEncoder().encode(encryptedData)));

      byte[] decryptedData = decrypt(privateKey, encryptedData);

        System.out.println("Decrypted key.... ");
        System.out.println(new String(decryptedData));
    }
}
4

1 回答 1

3

Java 加密 (JCA) 使用称为转换(或只是转换)的语法算法/模式/填充来指定所有密码。如果仅指定算法,则默认模式和填充。对于 RSA 没有实际的操作模式,并且转换 (ECB) 中的模式只是符合固定语法的占位符。但是有明显不同的填充方案。

我不是 Swift 的人,但从文档中看,0 实际上是 sigRaw,而 PKCS1 是 1。如果是这样,您使用 'raw' = no padding 进行加密,对应于 Java 的 NoPadding,因此使用 Java 默认的 PKCS1Padding 进行解密会像你发现的那样失败。试试"RSA/ECB/NoPadding"。或者更好的是,使用 PKCS1 加密使用 PKCS1(显式或默认)解密,因为...

警告:没有填充的 RSA 加密在语义上总是不安全的,并且取决于您如何使用它通常完全不安全(例如,攻击者可以快速解密您的所有数据)。这正是它不是默认值且不推荐的原因。但是,安全不是 stackoverflow 的主题;这是 crypto.SX 和 security.SX 的主题,其中已经有许多 Q 和 As 解释未填充的又名“教科书”或“幼稚”RSA 加密的危险。

于 2018-03-21T08:49:48.507 回答