Как расшифровать, чтобы вернуть исходную строку после шифрования? - PullRequest
0 голосов
/ 09 июля 2020

Я новичок в iOS и Swift. Я хотел зашифровать строку с помощью ключа publi c. Ключ publi c выглядел так:

"-----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.

1 Ответ

0 голосов
/ 10 июля 2020

Сердечное спасибо всем, кто пытался ее решить. Мне удалось это сделать самостоятельно. Вместо publi c key как строки я извлек publi c key как secKey, преобразовав мой crt-файл в der

...