37

Swift でアプリケーションを作成します。AES 暗号化および復号化機能が必要です。別の .Net ソリューションから暗号化されたデータを受け取りましたが、それを行う方法が見つかりません。

これは私の.net暗号化です:

 public static byte[] AES_Encrypt(byte[] bytesToBeEncrypted, byte[] passwordBytes)
    {
        byte[] encryptedBytes = null;

        byte[] saltBytes = new byte[] { 1, 2, 3, 4, 5, 6, 7, 8 };

        using (MemoryStream ms = new MemoryStream())
        {
            using (RijndaelManaged AES = new RijndaelManaged())
            {
                AES.KeySize = 256;
                AES.BlockSize = 128;

                var key = new Rfc2898DeriveBytes(passwordBytes, saltBytes, 1000);
                AES.Key = key.GetBytes(AES.KeySize / 8);
                AES.IV = key.GetBytes(AES.BlockSize / 8);

                AES.Mode = CipherMode.CBC;

                using (var cs = new CryptoStream(ms, AES.CreateEncryptor(), CryptoStreamMode.Write))
                {
                    cs.Write(bytesToBeEncrypted, 0, bytesToBeEncrypted.Length);
                    cs.Close();
                }
                encryptedBytes = ms.ToArray();
            }
        }

        return encryptedBytes;
    }

関数を迅速に復号化する必要があります。

4

13 に答える 13

36

CryptoSwift の

Swift 2 に更新

import Foundation
import CryptoSwift

extension String {
    func aesEncrypt(key: String, iv: String) throws -> String{
        let data = self.dataUsingEncoding(NSUTF8StringEncoding)
        let enc = try AES(key: key, iv: iv, blockMode:.CBC).encrypt(data!.arrayOfBytes(), padding: PKCS7())
        let encData = NSData(bytes: enc, length: Int(enc.count))
        let base64String: String = encData.base64EncodedStringWithOptions(NSDataBase64EncodingOptions(rawValue: 0));
        let result = String(base64String)
        return result
    }

    func aesDecrypt(key: String, iv: String) throws -> String {
        let data = NSData(base64EncodedString: self, options: NSDataBase64DecodingOptions(rawValue: 0))
        let dec = try AES(key: key, iv: iv, blockMode:.CBC).decrypt(data!.arrayOfBytes(), padding: PKCS7())
        let decData = NSData(bytes: dec, length: Int(dec.count))
        let result = NSString(data: decData, encoding: NSUTF8StringEncoding)
        return String(result!)
    }
}

使用法:

let key = "bbC2H19lkVbQDfakxcrtNMQdd0FloLyw" // length == 32
let iv = "gqLOHUioQ0QjhuvI" // length == 16
let s = "string to encrypt"
let enc = try! s.aesEncrypt(key, iv: iv)
let dec = try! enc.aesDecrypt(key, iv: iv)
print(s) // string to encrypt
print("enc:\(enc)") // 2r0+KirTTegQfF4wI8rws0LuV8h82rHyyYz7xBpXIpM=
print("dec:\(dec)") // string to encrypt
print("\(s == dec)") // true

iv (16) とキー (32) の長さが適切であることを確認してください。そうすれば、「ブロック サイズと初期化ベクトルは同じ長さでなければなりません!」というメッセージが表示されません。エラー。

于 2015-06-13T16:01:17.273 に答える
33

CryptoSwift の

更新されたSWIFT 4.*

func aesEncrypt() throws -> String {
    let encrypted = try AES(key: KEY, iv: IV, padding: .pkcs7).encrypt([UInt8](self.data(using: .utf8)!))
    return Data(encrypted).base64EncodedString()
}

func aesDecrypt() throws -> String {
    guard let data = Data(base64Encoded: self) else { return "" }
    let decrypted = try AES(key: KEY, iv: IV, padding: .pkcs7).decrypt([UInt8](data))
    return String(bytes: decrypted, encoding: .utf8) ?? self
}
于 2016-12-11T05:52:22.320 に答える
5

CommonCrypto を使用して、CommonCrypto HMAC の使いやすい Swift 実装から MihaelIsaev/HMAC.swift のコードを介してハッシュを生成していました。この実装は、Bridging-Header を使用せず、モジュール ファイルを作成します。

AESEncrypt と Decrypt を使用するために、HAMC.swift の「extension String {」内に関数を直接追加しました。

func aesEncrypt(key:String, iv:String, options:Int = kCCOptionPKCS7Padding) -> String? {
    if let keyData = key.dataUsingEncoding(NSUTF8StringEncoding),
        data = self.dataUsingEncoding(NSUTF8StringEncoding),
        cryptData    = NSMutableData(length: Int((data.length)) + kCCBlockSizeAES128) {

            let keyLength              = size_t(kCCKeySizeAES128)
            let operation: CCOperation = UInt32(kCCEncrypt)
            let algoritm:  CCAlgorithm = UInt32(kCCAlgorithmAES128)
            let options:   CCOptions   = UInt32(options)

            var numBytesEncrypted :size_t = 0

            let cryptStatus = CCCrypt(operation,
                algoritm,
                options,
                keyData.bytes, keyLength,
                iv,
                data.bytes, data.length,
                cryptData.mutableBytes, cryptData.length,
                &numBytesEncrypted)

            if UInt32(cryptStatus) == UInt32(kCCSuccess) {
                cryptData.length = Int(numBytesEncrypted)
                let base64cryptString = cryptData.base64EncodedStringWithOptions(.Encoding64CharacterLineLength)
                return base64cryptString
            }
            else {
                return nil
            }
    }
    return nil
}

func aesDecrypt(key:String, iv:String, options:Int = kCCOptionPKCS7Padding) -> String? {
    if let keyData = key.dataUsingEncoding(NSUTF8StringEncoding),
        data = NSData(base64EncodedString: self, options: .IgnoreUnknownCharacters),
        cryptData    = NSMutableData(length: Int((data.length)) + kCCBlockSizeAES128) {

            let keyLength              = size_t(kCCKeySizeAES128)
            let operation: CCOperation = UInt32(kCCDecrypt)
            let algoritm:  CCAlgorithm = UInt32(kCCAlgorithmAES128)
            let options:   CCOptions   = UInt32(options)

            var numBytesEncrypted :size_t = 0

            let cryptStatus = CCCrypt(operation,
                algoritm,
                options,
                keyData.bytes, keyLength,
                iv,
                data.bytes, data.length,
                cryptData.mutableBytes, cryptData.length,
                &numBytesEncrypted)

            if UInt32(cryptStatus) == UInt32(kCCSuccess) {
                cryptData.length = Int(numBytesEncrypted)
                let unencryptedMessage = String(data: cryptData, encoding:NSUTF8StringEncoding)
                return unencryptedMessage
            }
            else {
                return nil
            }
    }
    return nil
}

関数はRNCryptorから取得されました。Bridging-headerを使用せずに、ハッシュ関数と1つのファイル「HMAC.swift」に簡単に追加できました。これが、ハッシュと AES 暗号化/復号化を迅速に必要とする開発者にとって役立つことを願っています。

以下のように AESDecrypt を使用する例。

 let iv = "AA-salt-BBCCDD--" // should be of 16 characters.
 //here we are convert nsdata to String
 let encryptedString = String(data: dataFromURL, encoding: NSUTF8StringEncoding)
 //now we are decrypting
 if let decryptedString = encryptedString?.aesDecrypt("12345678901234567890123456789012", iv: iv) // 32 char pass key
 {                    
      // Your decryptedString
 }
于 2016-03-17T11:26:28.250 に答える
4

CryptoSwift は非常に興味深いプロジェクトですが、現時点では AES の速度制限がいくつかあります。深刻な暗号化を行う必要がある場合は注意してください。CommonCrypto を実装するブリッジの苦労を経験する価値があるかもしれません。

pureSwift 実装のための Marcin への BigUp

于 2016-01-05T10:56:07.587 に答える
1

私は解決策を見つけました、それは良いライブラリです。

クロス プラットフォーム 256 ビット AES 暗号化/復号化。

このプロジェクトには、すべてのプラットフォーム (C#、iOS、Android) で動作する 256 ビット AES 暗号化の実装が含まれています。主な目的の 1 つは、簡単な実装で AES をすべてのプラットフォームで機能させることです。

サポートされているプラ​​ットフォーム: iOS 、Android 、Windows (C#)。

https://github.com/Pakhee/Cross-platform-AES-encryption

于 2014-11-22T13:22:19.470 に答える
-4

以下のコードを試してみてください。

AES 暗号化

public static String getEncryptedString(String value) {
        try {
          byte[] key = your Key in byte array;
          byte[] input = sault in byte array

            return Base64.encodeToString(encrypt(value.getBytes("UTF-8"), key, input), Base64.DEFAULT);
        } catch (UnsupportedEncodingException e) {
            return "";
        }
    }


 public static byte[] encrypt(byte[] data, byte[] key, byte[] ivs) {
        try {
            Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
            SecretKeySpec secretKeySpec = new SecretKeySpec(key, "AES");
            byte[] finalIvs = new byte[16];
            int len = ivs.length > 16 ? 16 : ivs.length;
            System.arraycopy(ivs, 0, finalIvs, 0, len);
            IvParameterSpec ivps = new IvParameterSpec(finalIvs);
            cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec, ivps);
            return cipher.doFinal(data);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

AES 復号化

 public static String decrypt(String encrypted) throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, InvalidAlgorithmParameterException, IllegalBlockSizeException, BadPaddingException, UnsupportedEncodingException {

            byte[] key = your Key in byte array;
            byte[] input = sault in byte array


            SecretKeySpec skeySpec = new SecretKeySpec(key, "AES");
            IvParameterSpec ivSpec = new IvParameterSpec(input);
            Cipher ecipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
            ecipher.init(Cipher.DECRYPT_MODE, skeySpec, ivSpec);
            byte[] raw = Base64.decode(encrypted, Base64.DEFAULT);
            byte[] originalBytes = ecipher.doFinal(raw);
            String original = new String(originalBytes, "UTF8");
            return original;
        }
于 2019-07-11T10:33:55.857 に答える