2

メソッドを使用CCCrypt()して暗号化し、C# で復号化します。ただし、出力は元のプレーン テキストと同じではありません。

キーの長さは 256 ビットで、IV はデフォルト値です。

主なコードは次のとおりです。

// Encrypt
{
    // the key is 32 bytes (256 bits).
    Byte iv[] = { 0x12, 0x34, 0x56, 0x78, 0x90, 0xAB, 0xCD, 0xEF, 0x12, 0x34, 0x56, 0x78, 0x90, 0xAB, 0xCD, 0xEF };

    size_t numBytesEncrypted = 0;
    CCCryptorStatus cryptStatus = CCCrypt(kCCEncrypt,        // Operation
                                      kCCAlgorithmAES128, // Algorithm
                                      kCCOptionPKCS7Padding, // Option
                                      keyPtr,                // key
                                      kCCKeySizeAES256,      // key length
                                      iv, /* initialization vector (optional) */
                                      [self bytes],    // plain text
                                      dataLength, /* input */
                                      buffer,
                                      bufferSize, /* output */
                                      &numBytesEncrypted); //dataOutMove
    if (cryptStatus == kCCSuccess) {
        NSData *encryptedData = [NSData dataWithBytesNoCopy:buffer length:numBytesEncrypted];
        NSString *encryptedString = [encryptedData base64Encoding];
}

// Decrypted
{
    byte[] _key1 = { 0x12, 0x34, 0x56, 0x78, 0x90, 0xAB, 0xCD, 0xEF, 0x12, 0x34, 0x56, 0x78, 0x90, 0xAB, 0xCD, 0xEF };
    public static string AESDecrypt(string encryptedString, string key)
    {
        AesCryptoServiceProvider aes = new AesCryptoServiceProvider();
        aes.BlockSize = 128;
        aes.KeySize = 256;
        aes.IV = _key1;
        aes.Key = Encoding.UTF8.GetBytes(key);
        aes.Mode = CipherMode.CBC;
        aes.Padding = PaddingMode.PKCS7;

        // Convert Base64 strings to byte array
        byte[] src = System.Convert.FromBase64String(encryptedString);

        // decryption
        using (ICryptoTransform decrypt = aes.CreateDecryptor())
        {
            byte[] dest = decrypt.TransformFinalBlock(src, 0, src.Length);
            return Encoding.UTF8.GetString(dest);
        }
    }
}

編集: 理由はkeyPtr. 暗号化プロセスでは、次のようにキーを早い段階で処理します。

char keyPtr[kCCKeySizeAES256+1]; // room for terminator (unused)
bzero(keyPtr, sizeof(keyPtr)); // fill with zeroes (for padding) [key
getCString:keyPtr maxLength:sizeof(keyPtr)
encoding:NSUTF8StringEncoding];

ここで、これらのコードを次のように変更します。

NSData *keyData = [key dataUsingEncoding:NSUTF8StringEncoding];
NSUInteger keyLength = [keyData length];
Byte *keyPtr= (Byte *)malloc(keyLength);
memcpy(keyPtr, [keyData bytes], keyLength);

その後、正しい出力が得られました。問題はなくなりましたが、以前のバージョンのどこが悪いのか本当にわかりません。

4

2 に答える 2

3

暗号化は、小さなエラーでも失敗するように設計されています。キーがバイトごとに同じであることを明示的に確認する必要があります(文字ではなくバイトを確認してください)。IVについても同様です。CBC モードでデコードしています。暗号化が CBC モードであることは確かですか。コードで明示的に設定されていません。パディングも同様。暗号化方式が PKCS7 を使用していることは確かですか?

通常、デフォルト設定に依存せず、コードで明示的に設定してください。

最後のポイントとして、両側で同じバイト <-> 文字変換を使用していますか。繰り返しますが、何を使用しているかを明示する方がよいでしょう。たとえば、UTF-8 テキストには、UTF-8 変換では無視される初期 BOM が付属している場合がありますが、別の変換ではバイトに含まれます。

于 2013-08-02T12:40:55.200 に答える