无法使用1024次迭代进行AES 128位加密-iOS和C#.NET
本文关键字:加密 128位 -iOS NET AES 1024次 迭代 | 更新日期: 2023-09-27 17:58:24
我在.NET中使用128位AES加密和1024次迭代进行加密,并将本文作为参考:
http://steelmon.wordpress.com/2013/07/01/simple-interoperable-encryption-in-java-and-net/
.NET代码可以很好地进行加密:
class Cls_Security
{
private const int Iterations = 1024; // Recommendation is >= 1000
private const string SKeyDemo = "AbCdefGHiJklMnOpQ";// "_?73^?dVT3st5har3";
private const string SaltKeyDemo = "1234567890abcdEFGHi";//"!2S@LT&KT3st5har3EY";
private const string InitVectorDemo = "ABCDEFGH12345678";
public static bool EncryptFile(string srcFilename, string destFilename , bool IsDemo)
{
bool Res = false;
var aes = new AesManaged();
aes.BlockSize = 128;
aes.KeySize = 128;
var salt = Encoding.UTF8.GetBytes(SaltKeyDemo);
var key = new Rfc2898DeriveBytes("", salt, Iterations);
salt = Encoding.UTF8.GetBytes(SaltKeyDemo);
key = new Rfc2898DeriveBytes(SKeyDemo, salt, Iterations);
aes.Key = key.GetBytes(aes.KeySize / 8);
aes.IV = Encoding.ASCII.GetBytes(InitVectorDemo);
aes.Mode = CipherMode.CBC;
aes.Padding = PaddingMode.PKCS7;
ICryptoTransform transform = aes.CreateEncryptor(aes.Key, aes.IV);
using (var dest = new FileStream(destFilename, FileMode.Create, FileAccess.Write, FileShare.None))
{
using (var cryptoStream = new CryptoStream(dest, transform, CryptoStreamMode.Write))
{
using (var source = new FileStream(srcFilename, FileMode.Open, FileAccess.Read, FileShare.Read))
{
source.CopyTo(cryptoStream);
Res = true;
}
}
}
return Res;
}
}
Objective-C代码不能完美地解密文件:
#import <CommonCrypto/CommonCrypto.h>
#import "TestViewController.h"
#import "RNCryptManager.h"
@interface TestViewController ()
@end
@implementation TestViewController
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
NSString *url = [[NSBundle mainBundle] pathForResource:@"topics" ofType:@"xml"];
NSData *inputedData = [[NSData alloc] initWithContentsOfFile:url];
NSString *path = [NSString stringWithFormat:@"%@topics.xml",NSTemporaryDirectory()];
//this is what i can decrypt
NSString *key = @"AbCdefGHiJklMnOpQ";
//on .net side we are using
NSString *ivKey = @"ABCDEFGH12345678";
NSString *saltKey = @"1234567890abcdEFGHi";
if(inputedData)
{
NSData *iv = [ivKey dataUsingEncoding:NSUTF8StringEncoding];
NSData *salt = [saltKey dataUsingEncoding:NSUTF8StringEncoding]; ;
NSError *error = nil;
NSData *resultedData = [RNCryptManager decryptedDataForData:inputedData password:key iv:iv salt:salt error:&error];
[resultedData writeToFile:path atomically:YES];
NSLog(@"error === >> %@",error);
NSLog(@"RESULT PATH ===>>> %@",path);
}
}
+ (NSData *)doCipher:(NSData *)dataIn
iv:(NSData *)iv
key:(NSData *)symmetricKey
context:(CCOperation)encryptOrDecrypt
{
//int bytes[] = { 0x0, 0x1, 0x2, 0x3, 0x5, 0x6, 0x7, 0x8, 0xA, 0xB, 0xC, 0xD, 0xF, 0x10, 0x11, 0x12 };
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|kCCModeCBC,
symmetricKey.bytes,
kCCKeySizeAES128,
NULL,/*here u can provid iv byte array*/
dataIn.bytes,
dataIn.length,
dataOut.mutableBytes,
dataOut.length,
&cryptBytes);
if (ccStatus != kCCSuccess) {
NSLog(@"CCCrypt status: %d", ccStatus);
}
dataOut.length = cryptBytes;
return dataOut;
}
- (NSData *)AES128DecryptWithKey:(NSString *)key dataIn:(NSData *)dataIn iv:(NSData *)iv{
// 'key' should be 32 bytes for AES256, will be null-padded otherwise
char keyPtr[kCCKeySizeAES128+1]; // room for terminator (unused) // oorspronkelijk 256
bzero(keyPtr, sizeof(keyPtr)); // fill with zeroes (for padding)
// fetch key data
[key getCString:keyPtr maxLength:sizeof(keyPtr) encoding:NSUTF8StringEncoding];
NSUInteger dataLength = [dataIn length];
//See the doc: For block ciphers, the output size will always be less than or
//equal to the input size plus the size of one block.
//That's why we need to add the size of one block here
size_t bufferSize = dataLength + kCCBlockSizeAES128;
void *buffer = malloc(bufferSize);
size_t numBytesDecrypted = 0;
CCCryptorStatus cryptStatus = CCCrypt(kCCDecrypt, kCCAlgorithmAES128, kCCOptionPKCS7Padding,
keyPtr, kCCKeySizeAES128, // oorspronkelijk 256
[iv bytes] /* initialization vector (optional) */,
[dataIn bytes], dataLength, /* input */
buffer, bufferSize, /* output */
&numBytesDecrypted);
if (cryptStatus == kCCSuccess) {
//the returned NSData takes ownership of the buffer and will free it on deallocation
return [NSData dataWithBytesNoCopy:buffer length:numBytesDecrypted];
}
free(buffer); //free the buffer;
return nil;
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
@end
你能告诉我我做错了什么以及如何让它发挥作用吗?
同样的代码有效,只需确保迭代次数和所有其他参数对加密内容有效。
您的解密方法没有说它是CBC,您在.net.中使用它作为密码模式
更改解密方法中的以下代码
CCCryptorStatus cryptStatus = CCCrypt(kCCDecrypt, kCCAlgorithmAES128, kCCOptionPKCS7Padding,
keyPtr, kCCKeySizeAES128, // oorspronkelijk 256
[iv bytes] /* initialization vector (optional) */,
[dataIn bytes], dataLength, /* input */
buffer, bufferSize, /* output */
&numBytesDecrypted);
到此
CCCryptorStatus cryptStatus = CCCrypt(kCCDecrypt, kCCAlgorithmAES128, kCCOptionPKCS7Padding|kCCModeCBC,
keyPtr, kCCKeySizeAES128, // oorspronkelijk 256
[iv bytes] /* initialization vector (optional) */,
[dataIn bytes], dataLength, /* input */
buffer, bufferSize, /* output */
&numBytesDecrypted);