当前位置: 首页 > 知识库问答 >
问题:

解密aes/gcm/pkcs5padding iOS Swift

鄢选
2023-03-14

我正在尝试用AES解密来解密一个Base64Encoded字符串消息。

从输入中提取IV和加密文本

使用IV和相同的密码短语生成用于加密文本的密钥。密钥生成应遵循以下相同的步骤。

生成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.
        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.
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);
            }
        }
} 
 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"

任何线索将非常感谢,我想知道我是否错过了一些配置或数据转换时,试图转换在SWIFT。

共有1个答案

松秦斩
2023-03-14

我能够使用“CryptoSwift”框架解密输入,想知道我们是否可以使用苹果iOS的CommonCrypto框架解决同样的问题。

任何使用“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
    }
 类似资料:
  • 这是一个错误: 1.JS

  • 我正在编写一个Java程序来解密TLS1.2会话,它使用密码。我使用Wireshark录制了一个测试会话。主秘已知。 这里我只需要客户机密钥,因为我想解密一个客户机->服务器包。我按照RFC扩展了服务器和客户端密钥以及IVs。 即兴: 我从salt创建AES-GCM nonce(=客户端写IV)和显式nonce(=加密数据的前8字节)。 代码: 现在我把所有东西都输入到BouncyCastle中:

  • 节点模块: Java类:主要方法现在只是用于测试,稍后将被删除。

  • 我目前正在将我的C#AES-GCM密码代码转换为PHP。然而,经过一些研究,我的PHP系统加密的文本不能被C#one解密。我想知道这两种代码是否有区别: C#带弹跳壳: 下面是PHP系统: 有没有人能告诉我,PHP代码中是否有遗漏或不同之处,导致它们的工作方式有所不同?或者PHP函数和BouncyCastle函数之间是否存在某种内部差异,从而使它们有所不同?

  • 我使用AES方法对从txt文件调用的sentance进行加密。我使用了GCM模式并创建了一个特定的密钥。一切都在工作(代码如下)。 我尝试实现解密过程,也就是说,我只有密钥(HexMyKeyvalue)和加密消息(HexEncryptedOriginalMessage value)并且我想对其进行解密。但问题是我错过了一些东西... 我写了下面的代码,但我有错误消息。 TypeError:decr

  • 我一直在试图找出java安全/加密库的方法,我相信我在理解发生了什么方面取得了一些进展。我想我设法让加密部分工作了。在encrypt方法中,如果我只是尝试返回,我会得到一些看起来像加密文本的不可读的杂乱无章的东西。当我试图不返回它,而是继续调用decrypt并进行明文-->encrypt-->decrypt是我所拥有的一切时,问题就来了 所以我用一些明文调用encrypt,并尝试返回明文以确保它工