簡體   English   中英

使用iOs CCCrypt函數使用AES生成的C#解密base64字符串

[英]Decrypt a base64 string using C# generated by iOs CCCrypt function using AES

有人可以幫助將下面由iOS代碼生成的base64字符串解密為等效的C#。

我試圖在c#中以“在晚上8點在秘密位置遇見我”結尾。

iOS生成了以下加密:qd + SGaij5KSBScuLs3TpJS / 3Dew8fHTudcs / 5MG7Q1kqcrZzZycMgTcQuEEEED5f

此iOS代碼根據XCode 6中的要求成功加密和解密了數據。

預先感謝您的幫助和支持。

達倫

#import <CommonCrypto/CommonCryptor.h>

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.

    NSString *sData = @"Meet me at the secret location at 8pm";
    NSString *sIv = @"4QesEr03HwE5H1C+ICw7SA==";
    NSString *sKey = @"ovA6siPkyM5Lb9oNcnxLz676K6JK6FrJKk4efEUWBzg=";

    NSData *dData = [sData dataUsingEncoding:NSUTF8StringEncoding];
    NSData *dIv = [sIv dataUsingEncoding:NSUTF8StringEncoding];
    NSData *dKey = [sKey dataUsingEncoding:NSUTF8StringEncoding];

    NSData *dEncrypt = [self doCipher:dData iv:dIv key:dKey context:kCCEncrypt];

    NSData *dDecrypt = [self doCipher:dEncrypt iv:dIv key:dKey context:kCCDecrypt];
    NSString *sDecrypt = [[NSString alloc] initWithData:dDecrypt encoding:NSUTF8StringEncoding];
    NSLog(@"Decrypted Data: %@",sDecrypt);
}

- (NSData *)doCipher:(NSData *)dataIn
              iv:(NSData *)iv
             key:(NSData *)symmetricKey
         context:(CCOperation)encryptOrDecrypt
{
    CCCryptorStatus ccStatus   = kCCSuccess;
    size_t          cryptBytes = 0;    // Number of bytes moved to buffer.
    NSMutableData  *dataOut    = [NSMutableData dataWithLength:dataIn.length + kCCBlockSizeAES128];

    ccStatus = CCCrypt( encryptOrDecrypt,
                   kCCAlgorithmAES128,
                   kCCOptionPKCS7Padding,
                   symmetricKey.bytes,
                   kCCKeySizeAES128,
                   iv.bytes,
                   dataIn.bytes,
                   dataIn.length,
                   dataOut.mutableBytes,
                   dataOut.length,
                   &cryptBytes);

    if (ccStatus != kCCSuccess) {
        NSLog(@"CCCrypt status: %d", ccStatus);
    }

    dataOut.length = cryptBytes;

    NSString *base64 = [dataOut base64EncodedStringWithOptions:0];
    NSLog(@"%@",base64);

    return dataOut;
}

每個平台上的加密文本現在顯示為:

X / aopyVDDva / wJ3If / 5i73JGjwth9eH45Opxaaswgb8Kx3ynh8BhBTFRrHT0 / i3y

這是有效的C#代碼

注意:從https://github.com/Pakhee/Cross-platform-AES-encryption提取的C#代碼

namespace CryptoTest
{
    public partial class Default : System.Web.UI.Page
    {
        protected void Page_Load(object sender, EventArgs e)
        {
            string iv = "4QesEr03HwE5H1C+ICw7SA=="; // origional iv 128 bits
            string key = "ovA6siPkyM5Lb9oNcnxLz676K6JK6FrJKk4efEUWBzg="; // origional key 256 bits
            string message = "Meet me at the secret location at 8pm";

            CryptLib cryptLib = new CryptLib();
            string encryptedText = cryptLib.encrypt(message, key, iv);

            string originalMessage = cryptLib.decrypt(encryptedText, key, iv);
            Debug.WriteLine(originalMessage);
        }
    }

    public class CryptLib
    {
        UTF8Encoding _enc;
        RijndaelManaged _rcipher;
        byte[] _key, _pwd, _ivBytes, _iv;

        private enum EncryptMode { ENCRYPT, DECRYPT };

        public CryptLib()
        {
            _enc = new UTF8Encoding();
            _rcipher = new RijndaelManaged();
            _rcipher.Mode = CipherMode.CBC;
            _rcipher.Padding = PaddingMode.PKCS7;
            _rcipher.KeySize = 256;
            _rcipher.BlockSize = 128;
            _key = new byte[32];
            _iv = new byte[_rcipher.BlockSize / 8]; //128 bit / 8 = 16 bytes
            _ivBytes = new byte[16];
        }

        private String encryptDecrypt(string _inputText, string _encryptionKey, EncryptMode _mode, string _initVector)
        {
            string _out = "";// output string
            _pwd = Encoding.UTF8.GetBytes(_encryptionKey);
            _ivBytes = Encoding.UTF8.GetBytes(_initVector);
            int len = _pwd.Length;
            if (len > _key.Length)
            {
                len = _key.Length;
            }
            int ivLenth = _ivBytes.Length;
            if (ivLenth > _iv.Length)
            {
                ivLenth = _iv.Length;
            }
            Array.Copy(_pwd, _key, len);
            Array.Copy(_ivBytes, _iv, ivLenth);
            _rcipher.Key = _key;
            _rcipher.IV = _iv;
            if (_mode.Equals(EncryptMode.ENCRYPT))
            {
                //encrypt
                byte[] plainText = _rcipher.CreateEncryptor().TransformFinalBlock(_enc.GetBytes(_inputText), 0, _inputText.Length);
                _out = Convert.ToBase64String(plainText);
            }
            if (_mode.Equals(EncryptMode.DECRYPT))
            {
                //decrypt
                byte[] plainText = _rcipher.CreateDecryptor().TransformFinalBlock(Convert.FromBase64String(_inputText), 0, Convert.FromBase64String(_inputText).Length);
                _out = _enc.GetString(plainText);
            }
            _rcipher.Dispose();
            return _out;// return encrypted/decrypted string
        }

        public string encrypt(string _plainText, string _key, string _initVector)
        {
            return encryptDecrypt(_plainText, _key, EncryptMode.ENCRYPT, _initVector);
        }

        public string decrypt(string _encryptedText, string _key, string _initVector)
        {
            return encryptDecrypt(_encryptedText, _key, EncryptMode.DECRYPT, _initVector);
        }
    }
}

這是有效的iOS代碼

    #import <CommonCrypto/CommonCryptor.h>

    - (void)viewDidLoad {
        [super viewDidLoad];
        // Do any additional setup after loading the view, typically from a nib.

        NSString *sData = @"Meet me at the secret location at 8pm";
        NSString *sIv = @"4QesEr03HwE5H1C+ICw7SA==";
        NSString *sKey = @"ovA6siPkyM5Lb9oNcnxLz676K6JK6FrJKk4efEUWBzg=";

        NSData *dData = [sData dataUsingEncoding:NSUTF8StringEncoding];

        NSData *dEncrypt = [self doCipher:dData key:sKey iv:sIv context:kCCEncrypt];
        NSData *base64 = [dEncrypt base64EncodedDataWithOptions:0];
        NSString *sBase64 = [[NSString alloc] initWithData:base64 encoding:NSUTF8StringEncoding];
        NSLog(@"Base64 String: %@",sBase64);

        NSData *dDecrypt= [self decrypt:dEncrypt key:sKey iv:sIv];
        NSString *sDecrypt = [[NSString alloc] initWithData:dDecrypt encoding:NSUTF8StringEncoding];
        NSLog(@"Decrypted Data: %@",sDecrypt);
    }

    - (NSData *)doCipher:(NSData *)plainText
                     key:(NSString *)key
                      iv:(NSString *)iv
                 context:(CCOperation)encryptOrDecrypt
    {
        NSUInteger dataLength = [plainText length];

        size_t buffSize = dataLength + kCCBlockSizeAES128;
        void *buff = malloc(buffSize);

        size_t numBytesEncrypted = 0;

        NSData *dIv = [iv dataUsingEncoding:NSUTF8StringEncoding];
        NSData *dKey = [key dataUsingEncoding:NSUTF8StringEncoding];

        CCCryptorStatus status = CCCrypt(encryptOrDecrypt,
                                         kCCAlgorithmAES128,
                                         kCCOptionPKCS7Padding,
                                         dKey.bytes, kCCKeySizeAES256,
                                         dIv.bytes,
                                         [plainText bytes], [plainText length],
                                         buff, buffSize,
                                         &numBytesEncrypted);
        if (status == kCCSuccess) {
            return [NSData dataWithBytesNoCopy:buff length:numBytesEncrypted];
        }

        free(buff);
        return nil;
    }

給定的base64字符串qd+SGaij5KSBScuLs3TpJS/3Dew8fHTudcs/5MG7Q1kqcrZzZycMgTcQuEEEED5f是一個雙向打包。

首先必須對其進行base64解碼( 在C#中容易 ),然后必須使用正確的算法對其進行解密。 從給定的參數來看,它希望使用AES或Rijndael算法( 此處為示例代碼),您必須其中放入base64解碼字節,密鑰和IV。

之后,您希望獲得所需的數據。

因此,我為自己寫了一個示例,並且能夠使用C#加密和解密指定的消息。

但是,檢索到的加密消息不同於iOS生成的消息

您的iOS消息: qd+SGaij5KSBScuLs3TpJS/3Dew8fHTudcs/5MG7Q1kqcrZzZycMgTcQuEEEED5f我的C#消息: wC2dn+QVhOhf+NqZVskopLdh2XDAdG3SmczrKF+TjQsGfxu07BEhRdiDqkbGY80O

我只是做了一些小改動,然后稍微深了一些。 我看到的一件事是,您在iOS代碼中說密鑰的長度為256位。 但是您提供的密鑰只有128位的長度。 在這種情況下,C#似乎只是切換回128位密鑰長度(因為在下面的代碼中更改密鑰大小不會更改加密的字節)。 但是也許iOS中的CCCrypt有所不同。 因此,要么在您的iOS代碼中采用密鑰大小,要么提供一個256位密鑰,然后再次比較iOS和C#的結果。

例:

var message = @"Meet me at the secret location at 8pm";
var iv = @"4QesEr03HwE5H1C+ICw7SA==";
var key = @"ovA6siPkyM5Lb9oNcnxLz676K6JK6FrJKk4efEUWBzg=";

byte[] encryptedBytes;

using (var aesCryptoProvider = new AesCryptoServiceProvider())
{
    aesCryptoProvider.BlockSize = 128;
    aesCryptoProvider.KeySize = 256;
    aesCryptoProvider.IV = Convert.FromBase64String(iv);
    aesCryptoProvider.Key = Convert.FromBase64String(key);
    aesCryptoProvider.Padding = PaddingMode.PKCS7;
    aesCryptoProvider.Mode = CipherMode.CBC;

    using (var encryptor = aesCryptoProvider.CreateEncryptor())
    using (var memoryStream = new MemoryStream())
    using (var cryptoStream = new CryptoStream(memoryStream, encryptor, CryptoStreamMode.Write))
    using (var streamWriter = new StreamWriter(cryptoStream, Encoding.UTF8))
    {
        streamWriter.Write(message);
        streamWriter.Close();
        encryptedBytes = memoryStream.ToArray();
    }
}

var encryptedMessage = Convert.ToBase64String(encryptedBytes);
Console.WriteLine(encryptedMessage);

using (var aesCryptoProvider = new AesCryptoServiceProvider())
{
    aesCryptoProvider.BlockSize = 128;
    aesCryptoProvider.KeySize = 256;
    aesCryptoProvider.IV = Convert.FromBase64String(iv);
    aesCryptoProvider.Key = Convert.FromBase64String(key);
    aesCryptoProvider.Padding = PaddingMode.PKCS7;
    aesCryptoProvider.Mode = CipherMode.CBC;

    using (var decryptor = aesCryptoProvider.CreateDecryptor())
    using (var memoryStream = new MemoryStream(Convert.FromBase64String(encryptedMessage)))
    using (var cryptoStream = new CryptoStream(memoryStream, decryptor, CryptoStreamMode.Read))
    using (var streamReader = new StreamReader(cryptoStream, Encoding.UTF8))
    {
        Console.WriteLine(streamReader.ReadToEnd());
    }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM