【问题标题】:How to decrypt to get back the original string after encryption?加密后如何解密以取回原始字符串?
【发布时间】:2020-10-30 04:57:47
【问题描述】:

我是 iOS 和 Swift 的新手。我想用公钥加密一个字符串。公钥是这样的:

"-----BEGIN PUBLIC KEY-----
Some String
-----END PUBLIC KEY-----"

我搜索了一下,得到并实现了如下代码:

static func encrypt(string: String, publicKey: String?) -> String? {
        guard let publicKey = publicKey else { return nil }

        let keyString = publicKey.replacingOccurrences(of: "-----BEGIN PUBLIC KEY-----\n", with: "").replacingOccurrences(of: "\n-----END PUBLIC KEY-----", with: "")
        guard let data = Data(base64Encoded: keyString) else { return nil }

        var attributes: CFDictionary {
            return [kSecAttrKeyType         : kSecAttrKeyTypeRSA,
                    kSecAttrKeyClass        : kSecAttrKeyClassPublic,
                    kSecAttrKeySizeInBits   : 2048,
                    kSecReturnPersistentRef : kCFBooleanTrue] as CFDictionary
        }

        var error: Unmanaged<CFError>? = nil
        guard let secKey = SecKeyCreateWithData(data as CFData, attributes, &error) else {
            print(error.debugDescription)
            return nil
        }
        return encrypt(string: string, publicKey: secKey)
    }

    static func encrypt(string: String, publicKey: SecKey) -> String? {
        let buffer = [UInt8](string.utf8)

        var keySize   = SecKeyGetBlockSize(publicKey)
        var keyBuffer = [UInt8](repeating: 0, count: keySize)

        // Encrypto  should less than key length
        guard SecKeyEncrypt(publicKey, SecPadding.PKCS1, buffer, buffer.count, &keyBuffer, &keySize) == errSecSuccess else { return nil }
        return Data(bytes: keyBuffer, count: keySize).base64EncodedString()
    }
    

再次感谢 StackOverflow。现在的问题是我无法解密此函数返回的加密字符串。对于编码,我想要一个 2048 位的大小。 对于 Android,这就是加密的方式:

public String encryptKey() throws NoSuchPaddingException, NoSuchAlgorithmException, BadPaddingException, IllegalBlockSizeException, InvalidKeyException, CertificateException {

 

        publicKey = getPublicKey();

 

        Cipher oaepFromAlgo = Cipher.getInstance("RSA/NONE/OAEPWITHSHA-256ANDMGF1PADDING");
        oaepFromAlgo.init(Cipher.ENCRYPT_MODE, publicKey );
        //byte[] ct = oaepFromAlgo.doFinal(secretKey.toString().getBytes(StandardCharsets.UTF_8));
        byte[] ct = oaepFromAlgo.doFinal(secretKey.getEncoded());
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            return Base64.getEncoder().encodeToString(ct);
        }
        else{
            return android.util.Base64.encodeToString(ct,android.util.Base64.DEFAULT);
        }
    }

 

    private PublicKey getPublicKey() throws CertificateException {
        CertificateFactory f = CertificateFactory.getInstance("X.509");
        X509Certificate certificate = (X509Certificate)f.generateCertificate(getTrustedCertificatesInputStream());
        return certificate.getPublicKey();
    }

如果有人能指导我如何解密以及我的加密过程是否类似于 android,那将非常有帮助。

【问题讨论】:

    标签: ios swift iphone encryption public-key-encryption


    【解决方案1】:

    衷心感谢所有试图解决这个问题的人。我设法自己做到了。我没有将公钥作为字符串,而是通过将我的 crt 文件转换为 der 来提取公钥作为 secKey

    【讨论】:

      猜你喜欢
      • 2010-12-27
      • 1970-01-01
      • 1970-01-01
      • 2014-12-02
      • 2019-02-02
      • 1970-01-01
      • 2014-01-30
      • 1970-01-01
      • 2012-03-08
      相关资源
      最近更新 更多