OStack程序员社区-中国程序员成长平台

标题: c# - AES - c# 加密和 objective-c 解密不起作用 [打印本页]

作者: 菜鸟教程小白    时间: 2022-12-13 14:10
标题: c# - AES - c# 加密和 objective-c 解密不起作用

当我在 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# 的跨平台示例代码



Best Answer-推荐答案


第一步是以十六进制记录加密调用前后的所有输入和输出,以便验证是否相同。
还要验证所有参数是否相同且正确,这可能需要阅读文档以确定默认值。

实际的加密函数比较简单,只是一个函数调用,没有什么神秘的东西,只要输入正确就行了。

  1. 您没有为 C# 和 ObjC 代码提供相同的参数。 C#为ECB模式,ObjC为CBC模式(默认)。
    使用 CBC 模式。

  2. key Base64: "CAshKUlVCllbEwPmzS4cTg=="
    是十六进制 080B212949550A595B1303E6CD2E1C4E
    这是16个字节。
    在 C# 和 ObjC 中,您将 key 大小声明为 256 位(32 字节):分别为 aesAlg.KeySize = 256;kCCKeySizeAES256
    将 128 位 key 的 key 大小指定为 128 位。

  3. 在 ObjC 代码中,您不是对 key 和 iv 进行 Base64 解码。

  4. 没有理由使用第 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/






欢迎光临 OStack程序员社区-中国程序员成长平台 (https://ostack.cn/) Powered by Discuz! X3.4