无法使用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

你能告诉我我做错了什么以及如何让它发挥作用吗?

无法使用1024次迭代进行AES 128位加密-iOS和C#.NET

同样的代码有效,只需确保迭代次数和所有其他参数对加密内容有效。

您的解密方法没有说它是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);