23

iPhone で文字列を暗号化し、復号化のために .Net Web サービスに送信する必要があります。iPhone と .Net で暗号化/復号化できますが、iPhone からの暗号化された文字列は .Net で復号化できません。「パディングが無効であり、削除できません」というエラーが表示されます。

.Net コードは http://blog.realcoderscoding.com/index.php/2008/07/dot-net-encryption-simple-aes-wrapper/からのものです。

iPhone コードは、http: //nootech.wordpress.com/2009/01/17/symmetric-encryption-with-the-iphone-sdk/のサンプル コードを使用しています。

私の知る限り、私のキー設定は同じです:

result.BlockSize = 128; // iPhone: kCCBlockSizeAES128
result.KeySize = 128; // kCCBlockSizeAES128
result.Mode = CipherMode.CBC;
result.Padding = PaddingMode.PKCS7; // kCCOptionPKCS7Padding

暗号文を生成するさまざまな方法を試しました。こんにちは/こんにちは:

e0PnmbTg/3cT3W+92CDw1Q== in .Net

iPhoneではyrKe5Z7p7MNqx9+CbBvNqQ==

および「openssl enc -aes-128-cbc -nosalt -a -in hello.txt -pass pass:hello」は次を生成します: QA+Ul+r6Zmr7yHipMcHSbQ==

更新:この作業用のコードをここに投稿しました

4

3 に答える 3

15

少なくとも、異なる初期化ベクトル(IV)を使用しています。

  • .Netコードは、IVのキーを使用します。

    private static AesCryptoServiceProvider GetProvider(byte[] key)
    {
        //Set up the encryption objects
        AesCryptoServiceProvider result = new AesCryptoServiceProvider();
        byte[] RealKey = Encryptor.GetKey(key, result);
        result.Key = RealKey;
        result.IV = RealKey;
        return result;
    }

    private static byte[] GetKey(byte[] suggestedKey, AesCryptoServiceProvider p)
    {
        byte[] kRaw = suggestedKey;
        List kList = new List();
        for (int i = 0; i < p.LegalKeySizes[0].MinSize; i += 8 )
        {
            kList.Add(kRaw[i % kRaw.Length]);
        }
        byte[] k = kList.ToArray();
        return k;
    }

    これはおそらく次のようになりますkList.Add(kRaw[(i / 8) % kRaw.Length]);。それ以外の場合、長さが%8 == 0のキーは、同じ文字を繰り返し使用します。

    したがって、.Netで使用されるIV(およびキー)は次のとおりhleolhleolhleolhです。これはAPIの一部ではなく、指摘したラッパーコードが原因です(重大なバグがあります...)。

  • iPhoneコードはIVに0を使用します。

    // Initialization vector; dummy in this case 0's.
    uint8_t iv[kChosenCipherBlockSize];
    memset((void *) iv, 0x0, (size_t) sizeof(iv));
  • opensslは、デフォルトでランダムに生成されたソルトを付加します(これが出力が長くなる理由です!)。

openssl出力は、ランダムな初期化ベクトルを付加するため、より安全です。base64でデコードされた文字列の最初の数バイトは「Salted__」のようです。また、opensslにソルト(-nosalt)を使用しないように依頼したり、IV(-iv)を提供したりすることもできます。

基本的に、openssl、.Net、およびiPhoneは同じ暗号化を使用しているため、暗号化キーと初期化ベクトルを使用してAPIを初期化する方法に注意する必要があります。

于 2009-02-12T03:44:12.980 に答える
3

C#で

void test(){
   string ctB64 = encrypt("hola");
   Console.WriteLine(ctB64);  // the same as in objective-c
}

string encrypt(string input)
        {
            try
            {
                // Create a new instance of the AesManaged class.  This generates a new key and initialization vector (IV).
                AesManaged myAes = new AesManaged();

                // Override the cipher mode, key and IV
                myAes.Mode = CipherMode.CBC;
                myAes.IV = new byte[16] { 0x10, 0x16, 0x1F, 0xAD, 0x10, 0x10, 0xAA, 0x22, 0x12, 0x51, 0xF1, 0x1E, 0x15, 0x11, 0x1B, 0x10 }; // must be the same as in objective-c
                myAes.Key = Encoding.UTF8.GetBytes(“0123456789123456”);
                //CipherKey;  // Byte array representing the key
                myAes.Padding = PaddingMode.PKCS7;

                // Create a encryption object to perform the stream transform.
                ICryptoTransform encryptor = myAes.CreateEncryptor();

                // perform the encryption as required...
                MemoryStream ms = new MemoryStream();
                CryptoStream ct = new CryptoStream(ms, encryptor, CryptoStreamMode.Write);
                byte[] binput = Encoding.UTF8.GetBytes(input);
                ct.Write(binput, 0, binput.Length);
                ct.Close();
                byte [] result = ms.ToArray();
                return Convert.ToBase64String(result);
            }
            catch (Exception ex)
            {
                // TODO: Log the error 
                Console.WriteLine(ex);
                throw ex;
            }

        }

· Objective-c で、 https: //github.com/kelp404/CocoaSecurity から CocoaSecurity ライブラリを追加します。

#import "CocoaSecurity.h"
#import "Base64.h"

…

- (void) test{
 unsigned char bytes[] = { 0x10, 0x16, 0x1F, 0xAD, 0x10, 0x10, 0xAA, 0x22, 0x12, 0x51, 0xF1, 0x1E, 0x15, 0x11, 0x1B, 0x10 }; // must be the same as in c#

    NSData *iv = [NSData dataWithBytesNoCopy:bytes length:16 freeWhenDone:YES];
    NSData* key =   [@"0123456789123456" dataUsingEncoding:NSUTF8StringEncoding];

    CocoaSecurityResult *result = [CocoaSecurity aesEncrypt:@"hola" key:key iv:iv];
   NSLog(@"%@", result.base64); // the same as in c#


    NSData *data = [NSData dataWithBase64EncodedString:result.base64];
    CocoaSecurityResult *result2 = [CocoaSecurity aesDecryptWithData:data key:key iv:iv];

    NSLog(@"%@", result2.utf8String); // show "hola"

}
于 2015-12-11T01:11:49.490 に答える
2

テストで同じAESキーを使用していることを確認しますか?投稿のOpenSSLの例では、OpenSSLがキーとIVを取得するパスワードを使用しています(おそらくソルトも使用しています)。

ランダムな128ビットキーを生成し、このキーを16進形式でOpenSSLに指定します。

openssl enc -aes-128-cbc -a -in hello.txt -K KEY_IN_HEX -iv 0

安全なシステムではIV=0を使用しないでください。ただし、相互運用性をテストする場合は問題ありません。

于 2009-02-12T06:58:14.823 に答える