0

I'm pretty new to RSA Keys and Certificates and all of that. So I'm getting a PEM File from a network request, I understand the PEM file is basically the certificate without header and footer, so essentially I have a string. I need to create a PublicKey from that in order to Encrypt some text, but I think I'm doing something wrong. This is my code so far, I have talked to other teams (Android) and when they print out the Encrypted Data, they are getting a regular String and I'm getting lots of weird characters. Thanks in advance guys! (:

func encryptBase64(text: String, certificateStr: String) throws -> Data {
    let encryptionError = EncrpytionError(message: "There has been an issue with encryption")

    guard
        let certData = Data(base64Encoded: certificateStr),
        let certificate = SecCertificateCreateWithData(nil, certData as CFData),
        let publicKey = SecCertificateCopyKey(certificate)
    else {
        throw encryptionError
    }

    let algorithm: SecKeyAlgorithm = .rsaEncryptionOAEPSHA256AESGCM

    guard SecKeyIsAlgorithmSupported(publicKey, .encrypt, algorithm) else {
        throw encryptionError
    }
    guard let cipherText = SecKeyCreateEncryptedData(
        publicKey,
        algorithm,
        text.data(using: .utf8)! as CFData, nil)
    else {
        throw encryptionError
    }
    return cipherText as Data
}

And when I try to print cipherText as a String, I get this weird thing:

"D�aj�\\m꒤h,�A�{��8�~�\nY\u0003F�Cˤ�@��\"�\u0018�\u0007\u001fX@VC�U_��E\u0005dž1���X��\/4Px��P\u0016�8}% ��<��@�I_�K\u000e�\bR*�� ���斋�7,�%���F^q�\u0000\\�'�ZTD\u0013Q�_\u0010\u001f>i]&��B���@1\u0006\b��E\u0004�F���yS\u0013�3����SB)��m\u0017%��5ʲ����s\u0003��r�&�?�8b��W@\u001e��؞ۡ��8�s~��ӹ�u\"�2��U�&\b�3XV���˔Y��xt[\fm&P:\\�\f� y��6jy"

Android team is doing something like this on Kotlin:

private fun extractPublicKey(certificateString: String): PublicKey {
            val encodedCertificateBytes = certificateString.toByteArray()
            val decodedCertificateBytes = Base64.decode(encodedCertificateBytes, Base64.DEFAULT)
            val inStream = decodedCertificateBytes.inputStream()
            val certificateFactory = CertificateFactory.getInstance("X.509")
            val certificate = certificateFactory.generateCertificate(inStream)
            inStream.close()
            return certificate.publicKey
}
  • A ciphertext is a sequence of bytes which, when decoded with a charset encoding (such as UTF-8 with well-defined byte sequences), is corrupted and displayed as gibberish. If you want to convert a ciphertext to a string, a suitable binary-to-text encoding like Base64 must be used. This is generally true, so also for the Android side, which must therefore also apply a suitable encoding for the output (check with the Android team). – Topaco Jan 12 '23 at 08:33
  • I.e. the gibberish output itself is not an indication of an incorrect extraction of the key (or of some other bug in the encryption). For a test of the implementation, try to decrypt the ciphertext. – Topaco Jan 12 '23 at 08:53
  • Oh by any chance do you happen to have an example of how this can be achieved? – Fernando Ivan Perez Ruiz Jan 12 '23 at 16:27
  • 1
    As said before, you would have to find out the encoding of the Android side to use the same. Probably it is Base64 (because it is the most common), see e.g. [this SO post](https://stackoverflow.com/q/41502057/9014097). – Topaco Jan 13 '23 at 02:00

0 Answers0