当我在 C# 中加密并尝试在Objective C中解密它不起作用。 你能检查一下,让我知道我做错了什么。
C#代码
byte[] strKey = Convert.FromBase64String("CAshKUlVCllbEwPmzS4cTg==");
byte[] strIV = Convert.FromBase64String("HDAxBBlsKyVeIuS63kdCjg==");
byte[] strOutput = EncryptStringToBytes_Aes("satishsatyam", strKey, strIV);
string strOutput1 = ByteToString(strOutput);//i6BMzAlcnz6Z5dQKWkio7A==
static byte[] EncryptStringToBytes_Aes(string plainText, byte[] Key, byte[] IV)
{
byte[] encrypted;
// Create an Aes object
// with the specified key and IV.
using (Aes aesAlg = Aes.Create())
{
aesAlg.Mode = CipherMode.ECB;
aesAlg.Padding = PaddingMode.PKCS7;
aesAlg.KeySize = 256;
aesAlg.BlockSize = 128;
// Create an encryptor to perform the stream transform.
ICryptoTransform encryptor = aesAlg.CreateEncryptor(Key, IV);
// Create the streams used for encryption.
using (MemoryStream msEncrypt = new MemoryStream())
{
using (CryptoStream csEncrypt = new CryptoStream(msEncrypt, encryptor, CryptoStreamMode.Write))
{
using (StreamWriter swEncrypt = new StreamWriter(csEncrypt))
{
//Write all data to the stream.
swEncrypt.Write(plainText);
}
encrypted = msEncrypt.ToArray();
}
}
}
return encrypted;
}
private string ByteToString(byte[] objByte)
{
string strOutput = Convert.ToBase64String(objByte);
return strOutput;
}
Objective-C
//
// CryptLib.h
//
#import <CommonCrypto/CommonDigest.h>
#import <CommonCrypto/CommonCryptor.h>
#import <UIKit/UIKit.h>
@interface CryptLib : NSObject
- (NSData *)encryptNSData *)plainText keyNSString *)key ivNSString *)iv;
- (NSData *)decryptNSData *)encryptedText keyNSString *)key ivNSString *)iv;
- (NSData *)generateRandomIVsize_t)length;
- (NSString *) md5NSString *) input;
- (NSString*) sha256NSString *)key lengthNSInteger) length;
@end
#import "CryptLib.h"
#import "NSData+Base64.h"
@implementation CryptLib
-(NSData *)decrypt:(NSData *)encryptedText key:(NSString *)key iv:(NSString *)iv {
char keyPointer[kCCKeySizeAES256+2],// room for terminator (unused) ref: https://devforums.apple.com/message/876053#876053
ivPointer[kCCBlockSizeAES128+2];
BOOL patchNeeded;
patchNeeded = ([key length] > kCCKeySizeAES256+1);
if(patchNeeded)
{
NSLog(@"Key length is longer %lu", (unsigned long)[[[CryptLib alloc] md5:key] length]);
key = [key substringToIndex:kCCKeySizeAES256]; // Ensure that the key isn't longer than what's needed (kCCKeySizeAES256)
}
[key getCString:keyPointer maxLength:sizeof(keyPointer) encoding:NSUTF8StringEncoding];
[iv getCString:ivPointer maxLength:sizeof(ivPointer) encoding:NSUTF8StringEncoding];
if (patchNeeded) {
keyPointer[0] = '\0'; // Previous iOS version than iOS7 set the first char to '\0' if the key was longer than kCCKeySizeAES256
}
NSUInteger dataLength = [encryptedText length];
//see https://developer.apple.com/library/ios/documentation/System/Conceptual/ManPages_iPhoneOS/man3/CCryptorCreateFromData.3cc.html
// For block ciphers, the output size will always be less than or equal to the input size plus the size of one block.
size_t buffSize = dataLength + kCCBlockSizeAES128;
void *buff = malloc(buffSize);
size_t numBytesEncrypted = 0;
//refer to http://www.opensource.apple.com/source/CommonCrypto/CommonCrypto-36064/CommonCrypto/CommonCryptor.h
//for details on this function
//Stateless, one-shot encrypt or decrypt operation.
CCCryptorStatus status = CCCrypt(kCCDecrypt,/* kCCEncrypt, etc. */
kCCAlgorithmAES128, /* kCCAlgorithmAES128, etc. */
kCCOptionPKCS7Padding, /* kCCOptionPKCS7Padding, etc. */
keyPointer, kCCKeySizeAES256,/* key and its length */
ivPointer, /* initialization vector - use same IV which was used for decryption */
[encryptedText bytes], [encryptedText length], //input
buff, buffSize,//output
&numBytesEncrypted);
if (status == kCCSuccess) {
return [NSData dataWithBytesNoCopy:buff length:numBytesEncrypted];
}
free(buff);
return nil;
}
#import "ViewController.h"
#import "CryptLib.h"
@interface ViewController ()
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
libr = [[CryptLib alloc]init];
NSString *inputString = @"sample testing"; // this is the text that you want to encrypt.
NSLog(@"inputString : %@", inputString); //print the inputString text
NSString * _key = @"shared secret"; //secret key for encryption. To make encryption stronger, we will not use this key directly. We'll first hash the key next step and then use it.
// _key = [[CryptLib alloc] sha256:_key length:32]; //this is very important, 32 bytes = 256 bit
_key = @"CAshKUlVCllbEwPmzS4cTg==";
NSLog(@"_key data:: %@", _key); //print the _key text
// NSString * iv = [[[libr generateRandomIV:11] base64EncodingWithLineLength:0] substringToIndex:16]; //Here we are generating random initialization vector (iv). Length of this vector = 16 bytes = 128 bits
NSString * iv = @"HDAxBBlsKyVeIuS63kdCjg==";
NSLog(@"iv data:: %@", iv); //print the iv text
NSData *encryptedData = [libr decrypt:[@"i6BMzAlcnz6Z5dQKWkio7A==" dataUsingEncoding:NSUTF8StringEncoding] key:_key iv:iv];
NSString * decryptedText = [[NSString alloc] initWithData:encryptedData encoding:NSUTF8StringEncoding];
NSLog(@"decrypted data:: %@", decryptedText); //print the decrypted text
}
任何适用于 ios/Android,c# 的跨平台示例代码
第一步是以十六进制记录加密调用前后的所有输入和输出,以便验证是否相同。
还要验证所有参数是否相同且正确,这可能需要阅读文档以确定默认值。
实际的加密函数比较简单,只是一个函数调用,没有什么神秘的东西,只要输入正确就行了。
您没有为 C# 和 ObjC 代码提供相同的参数。 C#为ECB模式,ObjC为CBC模式(默认)。
使用 CBC 模式。
key Base64: "CAshKUlVCllbEwPmzS4cTg=="
是十六进制 080B212949550A595B1303E6CD2E1C4E
这是16个字节。
在 C# 和 ObjC 中,您将 key 大小声明为 256 位(32 字节):分别为 aesAlg.KeySize = 256;
和 kCCKeySizeAES256
。
将 128 位 key 的 key 大小指定为 128 位。
在 ObjC 代码中,您不是对 key 和 iv 进行 Base64 解码。
没有理由使用第 3 方 Base64 库。
更新了示例代码,没有错误检查:不适用于生产:
// First convert Base64 strings to data
NSString *stringIn = @"satishsatyam";
NSData *dataIn = [stringIn dataUsingEncoding:NSUTF8StringEncoding];
NSData *iv = [[NSData alloc] initWithBase64EncodedString"HDAxBBlsKyVeIuS63kdCjg==" options:0];
NSData *key = [[NSData alloc] initWithBase64EncodedString"CAshKUlVCllbEwPmzS4cTg==" options:0];
// Encryption
size_t encryptBytes = 0;
NSMutableData *encrypted = [NSMutableData dataWithLength:stringIn.length + kCCBlockSizeAES128];
CCCrypt(kCCEncrypt,
kCCAlgorithmAES,
kCCOptionPKCS7Padding, // CBC is the default mode
key.bytes, kCCKeySizeAES128,
iv.bytes,
dataIn.bytes, dataIn.length,
encrypted.mutableBytes, encrypted.length,
&encryptBytes);
encrypted.length = encryptBytes;
NSLog(@"encrypted hex: %@", encrypted);
NSLog(@"encrypted Base64: %@", [encrypted base64EncodedStringWithOptions:0]);
// Decryption
size_t decryptBytes = 0;
NSMutableData *decrypted = [NSMutableData dataWithLength:encrypted.length];
CCCrypt(kCCDecrypt,
kCCAlgorithmAES,
kCCOptionPKCS7Padding, // CBC is the default mode
key.bytes, kCCKeySizeAES128,
iv.bytes,
encrypted.bytes, encrypted.length,
decrypted.mutableBytes, decrypted.length,
&decryptBytes);
decrypted.length = decryptBytes;
NSLog(@"decrypted in hex: %@", decrypted);
NSLog(@"decrypted string: %@", [[NSString alloc] initWithData:decrypted encoding: NSUTF8StringEncoding]);
输出:
encrypted as hex: cbdb58fe ad464126 ea90252b 2ff52276
encrypted Base64: y9tY/q1GQSbqkCUrL/Uidg==
decrypted as hex: 73617469 73687361 7479616d
decrypted string: satishsatyam
关于c# - AES - c# 加密和 objective-c 解密不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35297582/
欢迎光临 OGeek|极客世界-中国程序员成长平台 (https://ogeek.cn/) | Powered by Discuz! X3.4 |