[英]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.