Расшифровка AES/GCM/PKCS5Padding iOS Swift

Я пытаюсь расшифровать сообщение Base64Encoded String с расшифровкой AES.

Зашифрованное сообщение (строка Base64Encoded): tNC6umcfBS / gelbo2VJF3i4LAhUKMp4oDHWN5KyYUTWeJIQKKYx6oAcQnGncIrPJNC1tUYMKV4kJQj3q9vocrxcjgWGV4kJQj3q9vocrxcjgW04kJQj3q9vocrxcjgwd05

Пароль (строка) = "SOMEPASSWORDSTRING"

Шаги по расшифровке сообщения:

  1. Данные должны быть декодированы из базы 64 в обычную строку.

  2. Извлеките IV и зашифрованный текст из ввода

  3. Используйте IV и ту же парольную фразу для генерации ключа, который использовался для шифрования текста. Для генерации ключа необходимо выполнить те же действия, что и ниже.

  4. Генерируется секретный ключ PBE (256 бит)

        a.    Specs created with passphrase and IV as salt, 62233 as iteration count
        b.    Used PBKDF2WithHmacSHA256 to generate a secret factory because it's appropriate for turning passwords into keys.
        c.    This key is further encoded and converted to another key with AES encryption.
    
  5. С помощью сгенерированного ключа и IV инициализируйте шифр точно так же, как показано ниже.

  6. Этот ключ инициализирует объект шифра

            a.    Used AES in GCM, GCM specs are prepared using tag size of 128 bits and the IV
            b.    Cipher object is initialized using AES/GCM/PKCS5Padding.
            c.    Based on operational mode the cipher is initialized with op mode(encryption), secret key and GCM params.
    
  7. Сгенерируйте шифр, чтобы получить сообщение из зашифрованного текста.

Ниже приведен код JAVA, который работает для расшифровки входного сообщения.

public class Decryption {
    private static final String KEY_GENERATING_ALGO = "PBKDF2WithHmacSHA256";
      private static final String ENCRYPTION = "AES";
      private static final String TRANSFORMATION_ALGORITHM= "AES/GCM/PKCS5Padding";
       
      private static final int KEY_SIZE_BITS = 256;
      private static final int TAG_SIZE_BITS = 128;
      private static final int ITERATION_COUNT  = 62233;
      
    // Use following sample data to test the decryption-
//tNC6umcfBS/gelbo2VJF3i4LAhUKMp4oDHWN5KyYUTWeJIQKKYx6oAcQnGncIrPJNC1tUYMKV4kJQj3q9voIOrxc1n7FmRFvDXeRgWGNcGYO66dH3VjoEgF0oxZOpfzwSZKSv3Jm7Q==
      
      // This key has is base 64 encoded with IV prepended with encrypted text
      public Cipher initCipher(int encryptMode, String password, byte[] iv) throws InvalidKeySpecException {
            try {
                GCMParameterSpec gcmparams = new GCMParameterSpec(TAG_SIZE_BITS, iv);
                PBEKeySpec pbeKeySpec = new PBEKeySpec(password.toCharArray(), iv, ITERATION_COUNT, KEY_SIZE_BITS);
                SecretKeyFactory factory = SecretKeyFactory.getInstance(KEY_GENERATING_ALGO);
                SecretKey pbeKey = factory.generateSecret(pbeKeySpec);
                byte[] keyBytes = pbeKey.getEncoded();
                SecretKey key = new SecretKeySpec(keyBytes, ENCRYPTION);
                Cipher cipher = Cipher.getInstance(TRANSFORMATION_ALGORITHM);
                cipher.init(encryptMode, key, gcmparams);
                return cipher;
            } catch (NoSuchAlgorithmException | NoSuchPaddingException | InvalidKeyException
                    | InvalidAlgorithmParameterException | InvalidKeySpecException ex) {
                throw new AssertionError(ex);
            }
        }
    //Decryption Algo
        public String decrypt(String encrypted){
            byte[] decFeeder = Base64.getDecoder().decode(encrypted);
            String key = "someKey"; // A new key will be provided by APIF through a secure channel
            char[] password = key.toCharArray();
            try {
                byte[] iv = Arrays.copyOfRange(decFeeder, 0, 32);
                byte[] ciphertext = Arrays.copyOfRange(decFeeder, iv.length, decFeeder.length);
                Cipher cipher = initCipher(Cipher.DECRYPT_MODE, key, iv);
                byte[] message = cipher.doFinal(ciphertext);
                String decrypted = new String(message);
                return decrypted;
            } catch (IllegalBlockSizeException | BadPaddingException | InvalidKeySpecException ex) {
                throw new AssertionError(ex);
            }
        }
} 

Я использовал приведенный ниже код в Swift для генерации того же кода JAVA, что и выше, но я не могу расшифровать сообщение /cipherText.

 func aesDecrypt(encryptedData: Data, password: String) -> Data? {
       
        let iv = Array([UInt8](encryptedData)[0 ..< 33])
        let ivData = Data(iv)
        let encryptedCipher = [UInt8](encryptedData)[iv.count ..< encryptedData.count]
        let encryptedCipherData = Data(encryptedCipher)
        
        let passwordKey = createKey(password:Data(password.utf8) , salt: ivData)

        var decryptSuccess = false
        let size = (encryptedCipher.count) + kCCBlockSizeAES128
        var clearTextData = Data.init(count: size)
        
        var numberOfBytesDecrypted : size_t = 0
        let cryptStatus = ivData.withUnsafeBytes {ivBytes in
            clearTextData.withUnsafeMutableBytes {clearTextBytes in
                encryptedCipherData.withUnsafeBytes {encryptedBytes in
                    passwordKey.withUnsafeBytes {keyBytes in
                        CCCrypt(CCOperation(kCCDecrypt),
                                CCAlgorithm(kCCAlgorithmAES128),
                                CCOptions(kCCOptionPKCS7Padding),
                                keyBytes,
                                passwordKey.count,
                                ivBytes,
                                encryptedBytes,
                                (encryptedCipher.count),
                                clearTextBytes,
                                size,
                                &numberOfBytesDecrypted)
                    }
                }
            }
        }
        if cryptStatus == Int32(kCCSuccess)
        {
            clearTextData.count = numberOfBytesDecrypted
            debugPrint(clearTextData)
            decryptSuccess = true
        }
        
        
        return decryptSuccess ? clearTextData : Data.init(count: 0)
    }

    func createKey(password: Data, salt: Data) -> Data? {
           let length = kCCKeySizeAES256
           var status = Int32(0)
           var derivedBytes = [UInt8](repeating: 0, count: length)
           password.withUnsafeBytes { (passwordBytes: UnsafePointer<Int8>!) in
               salt.withUnsafeBytes { (saltBytes: UnsafePointer<UInt8>!) in
                   status = CCKeyDerivationPBKDF(CCPBKDFAlgorithm(kCCPBKDF2),  // algorithm
                                                 passwordBytes,                // password
                                                 password.count,               // passwordLen
                                                 saltBytes,                    // salt
                                                 salt.count,                   // saltLen
                                                 UInt32(kCCPRFHmacAlgSHA256),  // prf
                                                 UInt32(62233),                // rounds
                                                 &derivedBytes,                // derivedKey
                                                 length)                       // derivedKeyLen
               }
           }
           guard status == 0 else {
              return nil
           }
           return Data(bytes: UnsafePointer<UInt8>(derivedBytes), count: length)
       }

Применение:

 guard let encryptedData = Data(base64Encoded: input) else{
  return nil
}
let decryptData = aesDecrypt3(encryptedData: encryptedData)
let decryptedMessage = String(data: decryptData, encoding: .utf8) ?? "Unable to Decrypt"

Мы будем очень благодарны за любые потенциальные клиенты, мне интересно, не хватает ли мне какой-либо конфигурации или преобразования данных при попытке быстрого преобразования.

1 ответ

Решение

Мне удалось расшифровать ввод с помощью фреймворка "CryptoSwift", и мне было интересно, сможем ли мы решить то же самое, используя фреймворк CommonCrypto для Apple iOS.

Будем очень признательны за любые лиды с использованием CommonCrypto.

 class func decryptCode123(_ cipher:String)-> String{
        
        let key = "SOMEKEY"
        
        var keyBytes: [UInt8] = []
        var codeBytes: [UInt8] = []
        var code = ""

        if let keyData = NSData(base64Encoded:key, options: .ignoreUnknownCharacters) {
            keyBytes = [UInt8](keyData as Data)
        }
        if let codeData = NSData(base64Encoded: cipher, options: .ignoreUnknownCharacters) {
            codeBytes = [UInt8](codeData as Data)
        }

        debugPrint(codeBytes)

        let codeBytescount = [UInt8](codeBytes).count

        let iv = Array([UInt8](codeBytes)[0 ..< 32])
        let cipher = Array([UInt8](codeBytes)[iv.count ..< codeBytescount])
        do{
            let gcm = GCM(iv: iv, mode: .combined)
            let derKey = createKey(password:Data(key.utf8), salt: Data(iv))!
            
            keyBytes = [UInt8](derKey)
            
            let aes = try AES(key: keyBytes, blockMode: gcm, padding: .pkcs5)
            
            print("aes created")
            let decrypted = try aes.decrypt(cipher)
            print("decrypted completed")
            if let decryptedString = String(bytes: decrypted, encoding: .utf8) {
                code = decryptedString
            }
            
            debugPrint(code)

        }catch let error as AES.Error {
            debugPrint(error.localizedDescription)
            return code
        } catch {
            return code
        }
        return code
    }
Другие вопросы по тегам