AES chiffrer et déchiffrer
J'écris une application par swift, j'ai besoin de la fonctionnalité AES Encrypt et Decrypt, j'ai reçu des données cryptées d'une autre solution. Net, mais je ne trouve rien pour le faire.
C'est mon cryptage. 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;
}
J'ai besoin de déchiffrer la fonction dans swift.
8 réponses
CryptoSwift Exemple
Mise à jour vers 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!)
}
}
Utilisation:
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
Assurez-vous que vous avez la bonne longueur de iv (16) et key (32) alors vous ne frapperez pas "Block size et le vecteur D'initialisation doit être de la même longueur!" erreur.
CryptoSwift Exemple
Mise à jour 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: Data(decrypted).bytes, encoding: .utf8) ?? "Could not decrypt"
}
Le Code fourni par SHS ne fonctionnait pas pour moi, mais celui-ci l'a apparemment fait (j'ai utilisé un en-tête de pontage: #import <CommonCrypto/CommonCrypto.h>
):
extension String {
func aesEncrypt(key:String, iv:String, options:Int = kCCOptionPKCS7Padding) -> String? {
if let keyData = key.data(using: String.Encoding.utf8),
let data = self.data(using: String.Encoding.utf8),
let cryptData = NSMutableData(length: Int((data.count)) + 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 as NSData).bytes, keyLength,
iv,
(data as NSData).bytes, data.count,
cryptData.mutableBytes, cryptData.length,
&numBytesEncrypted)
if UInt32(cryptStatus) == UInt32(kCCSuccess) {
cryptData.length = Int(numBytesEncrypted)
let base64cryptString = cryptData.base64EncodedString(options: .lineLength64Characters)
return base64cryptString
}
else {
return nil
}
}
return nil
}
func aesDecrypt(key:String, iv:String, options:Int = kCCOptionPKCS7Padding) -> String? {
if let keyData = key.data(using: String.Encoding.utf8),
let data = NSData(base64Encoded: self, options: .ignoreUnknownCharacters),
let 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 as NSData).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 as Data, encoding:String.Encoding.utf8)
return unencryptedMessage
}
else {
return nil
}
}
return nil
}
}
À Partir de mon ViewController
:
let encoded = message.aesEncrypt(key: keyString, iv: iv)
let unencode = encoded?.aesDecrypt(key: keyString, iv: iv)
Il existe une intéressante bibliothèque Open Source "pure-swift":
-
CryptoSwift: https://github.com/krzyzanowskim/CryptoSwift
Il prend en charge: AES-128, AES-192, AES-256, ChaCha20
Exemple avec AES decrypt (obtenu à partir du projet README.md fichier):
import CryptoSwift
let setup = (key: keyData, iv: ivData)
let decryptedAES = Cipher.AES(setup).decrypt(encryptedData)
CryptoSwift est un projet très intéressant mais pour l'instant il a quelques limitations de vitesse AES. Soyez prudent si vous avez besoin de faire un crypto sérieux - il pourrait être utile de passer par la douleur de la mise en œuvre du pont CommonCrypto.
BigUps à Marcin pour l'implémentation de pureSwift
J'utilisais CommonCrypto pour générer du hachage à travers le code de MihaelIsaev/HMAC.swift de implémentation rapide facile à utiliser de CommonCrypto HMAC . Cette implémentation est sans utiliser Bridging-Header, avec création de fichier de Module.
Maintenant, pour utiliser AESEncrypt et Decrypt, j'ai directement ajouté les fonctions à l'intérieur de "extension String {"dans HAMC.Swift.
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
}
Les fonctions ont été prises à partir de RNCryptor . C'était un ajout facile dans les fonctions de hachage et dans un fichier unique " HMAC.swift", sans utiliser Bridging-header. J'espère que cela sera utile pour les développeurs dans swift nécessitant le hachage et le cryptage/décryptage AES.
Exemple d'utilisation de L'AESDecrypt comme ci-dessous.
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
}
Voici une bibliothèque utilisant la nouvelle API WebCrypto .
Aucun en-tête de pontage requis et c'est assez plus rapide que CryptoSwift.
Https://github.com/etienne-martin/WebCrypto.swift
Cryptage par mot de passe
Cryptage
let crypto = WebCrypto()
let input = Data("This is a string".utf8)
let password = "password123"
crypto.encrypt(data: input, password: password, callback: {(encrypted: Data?, error: Error?) in
print(encrypted!)
})
Décryptage
crypto.decrypt(data: encrypted, password: password, callback: {(decrypted: Data?, error: Error?) in
print(String(data: decrypted!, encoding: .utf8)!)
})
Chiffrement par clé
Cryptage
let crypto = WebCrypto()
let input = Data("This is a string".utf8)
let key = "6f0f1c6f0e56afd327ff07b7b63a2d8ae91ab0a2f0c8cd6889c0fc1d624ac1b8"
let iv = "92c9d2c07a9f2e0a0d20710270047ea2"
crypto.encrypt(data: input, key: key, iv: iv, callback: {(encrypted: Data?, error: Error?) in
print(encrypted!)
})
Décryptage
crypto.decrypt(data: encrypted, key: key, iv: iv, callback: {(encrypted: Data?, error: Error?) in
print(String(data: decrypted!, encoding: .utf8)!)
})
Avertissement: j'ai écrit cette bibliothèque.
J'ai trouvé la solution, c'est une bonne bibliothèque.
Cross plate-forme 256bit AES cryptage / décryptage.
Ce projet contient l'implémentation du cryptage AES 256 bits qui fonctionne sur toutes les plateformes (C#, iOS, Android). L'un des objectifs clés est de faire fonctionner AES sur toutes les plates-formes avec une implémentation simple.
Plates-Formes Prises En Charge: iOS , Android , Windows (C#).