简体   繁体   English

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

[英]Unable to do AES 128 bit encryption with 1024 iterations - iOS and C# .NET

I am using 128 bit AES encryption with 1024 iterations for encryption in .NET, using this article as a reference: 我使用128位AES加密和1024次迭代来在.NET中进行加密,使用本文作为参考:

http://steelmon.wordpress.com/2013/07/01/simple-interoperable-encryption-in-java-and-net/ http://steelmon.wordpress.com/2013/07/01/simple-interoperable-encryption-in-java-and-net/

The .NET code does the encryption fine: .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;
    }
}

The Objective-C code doesn't decrypt the file perfectly: 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

Could you please tell me what I'm doing wrong and how to get it to work? 您能告诉我我做错了什么以及如何使其正常工作吗?

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

Your decryption method doesn't say it is CBC, which you are using as a cipher mode in the .net. 您的解密方法并不表示它是CBC,您正在.net中将其用作密码模式。

Change the following code in your decrypt method 在您的解密方法中更改以下代码

CCCryptorStatus cryptStatus = CCCrypt(kCCDecrypt, kCCAlgorithmAES128, kCCOptionPKCS7Padding,
                                          keyPtr, kCCKeySizeAES128, // oorspronkelijk 256
                                          [iv bytes] /* initialization vector (optional) */,
                                          [dataIn bytes], dataLength, /* input */
                                          buffer, bufferSize, /* output */
                                          &numBytesDecrypted);

To this 对此

CCCryptorStatus cryptStatus = CCCrypt(kCCDecrypt, kCCAlgorithmAES128, kCCOptionPKCS7Padding|kCCModeCBC,
                                          keyPtr, kCCKeySizeAES128, // oorspronkelijk 256
                                          [iv bytes] /* initialization vector (optional) */,
                                          [dataIn bytes], dataLength, /* input */
                                          buffer, bufferSize, /* output */
                                          &numBytesDecrypted);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM