4

iPhone で文字列を暗号化し、トリプル DES を使用して復号化するために .Net に送信する必要があります。iPhone と .Net で暗号化/復号化できますが、両方のプラットフォームで異なる結果が得られます。

ここでは、.Net と iPhone の間の AES による暗号化/復号化とまったく同じコードを使用します。

.net を変更したのは暗号化アルゴリズムだけなので、AesCryptoServiceProvider と書かれている場所に TripleDesServiceProvider を入れました。

.net のように、私が変更したのは暗号化アルゴリズムだけです。そのため、kCCAlgorithmAES128 と表示されている場所には、kCCAlgorithm3DES を配置します。

私は何が欠けていますか?

[アップデート]

ご回答ありがとうございます。

同じプラットフォームにとどまる場合、問題なく暗号化/復号化できますが、iPhone で暗号化し、.net で復号化すると、プラットフォームごとに同じ入力で異なる結果が得られるため、問題が発生します。

Overslackedが言ったように、問題はsaltに関係していると思いますが、アルゴリズムが各プラットフォームで使用しているshaまたはmd5のドキュメント、またはこれをカスタマイズするためのパラメーターを見つけることができませんでした.

これが私がiPhoneで実際に使用しているコードです。

int main(int argc, char *argv[]){
    NSString * _secret = @"hello";    
    NSString * _key = @"1234567890";    
    _out = [self doCipher:_secret key:_key context:kCCEncrypt];    
    NSLog(@"encrypted data in str: %@", _out);    
    _outDecrypted = [StringEncryption doCipher:_out key:_key context:kCCDecrypt];    
    NSLog(@"decrypted data in str: %@", _outDecrypted);    
}

+ (NSString *)doCipher:(NSString *)sTextIn key:(NSString *)sKey
               context:(CCOperation)encryptOrDecrypt {

    NSMutableData * dTextIn;
    if (encryptOrDecrypt == kCCDecrypt) {    
        dTextIn = [[[NSData alloc] base64DecodeString:sTextIn ]mutableCopy];    
    }    
    else{    
        dTextIn = [[sTextIn dataUsingEncoding: NSASCIIStringEncoding]mutableCopy];    
    }       
    NSMutableData * dKey = [[sKey dataUsingEncoding:NSASCIIStringEncoding]mutableCopy];            
    [dKey setLength:24];        
    uint8_t *bufferPtr1 = NULL;    
    size_t bufferPtrSize1 = 0;    
    size_t movedBytes1 = 0;    
    uint8_t iv[kCCBlockSize3DES];    
    memset((void *) iv, 0x0, (size_t) sizeof(iv));    
    bufferPtrSize1 = ([sTextIn length] + kCCBlockSize3DES) & ~(kCCBlockSize3DES -1);    
    bufferPtr1 = malloc(bufferPtrSize1 * sizeof(uint8_t));    
    memset((void *)bufferPtr1, 0x00, bufferPtrSize1);    
    ccStatus = CCCrypt(encryptOrDecrypt, // CCOperation op    
        kCCAlgorithm3DES, // CCAlgorithm alg    
        kCCOptionPKCS7Padding, // CCOptions options    
        [dKey bytes], // const void *key    
        [dKey length], // size_t keyLength    
        iv, // const void *iv    
        [dTextIn bytes], // const void *dataIn
        [dTextIn length],  // size_t dataInLength    
        (void *)bufferPtr1, // void *dataOut    
        bufferPtrSize1,     // size_t dataOutAvailable 
        &movedBytes1);      // size_t *dataOutMoved     
    NSString * sResult;    
    if (encryptOrDecrypt == kCCDecrypt){    
        sResult = [[[ NSString alloc] initWithData:[NSData dataWithBytes:bufferPtr1     
                           length:movedBytes1] encoding:NSASCIIStringEncoding] autorelease];    
    }    
    else {    
        NSData *dResult = [NSData dataWithBytes:bufferPtr1 length:movedBytes1];    
        sResult = [dResult base64EncodeData:dResult];    
    }       
    return sResult;
}   

これが私が.netに使用しているコードです

    class Program
    {
        static void Main(string[] args)
        {
           string key = "1234567890";
           string secret = "hello";
           string crypto = EncryptedString.EncryptString(secret, key);
           Console.WriteLine(crypto);
           secret = EncryptedString.DecryptString(crypto, key);
           Console.WriteLine(secret);
           Main(null); 

        }

    }


 public class EncryptedString
    {
        public static string EncryptString(string plainSourceStringToEncrypt, string passPhrase)
        {
            //Set up the encryption objects
            using (TripleDESCryptoServiceProvider acsp = GetProvider(Encoding.ASCII.GetBytes(passPhrase)))
            {
                byte[] sourceBytes = Encoding.ASCII.GetBytes(plainSourceStringToEncrypt);
                ICryptoTransform ictE = acsp.CreateEncryptor();

                //Set up stream to contain the encryption
                MemoryStream msS = new MemoryStream();

                //Perform the encrpytion, storing output into the stream
                CryptoStream csS = new CryptoStream(msS, ictE, CryptoStreamMode.Write);
                csS.Write(sourceBytes, 0, sourceBytes.Length);
                csS.FlushFinalBlock();

                //sourceBytes are now encrypted as an array of secure bytes
                byte[] encryptedBytes = msS.ToArray(); //.ToArray() is important, don't mess with the buffer
                String b64 =  System.Text.ASCIIEncoding.ASCII.GetString(encryptedBytes);
                return Convert.ToBase64String(encryptedBytes);
            }
        }


        public static string DecryptString(string base64StringToDecrypt, string passphrase)
        {
            //Set up the encryption objects
            using (TripleDESCryptoServiceProvider acsp = GetProvider(Encoding.Default.GetBytes(passphrase)))
            {
                byte[] RawBytes = Convert.FromBase64String(base64StringToDecrypt);
                ICryptoTransform ictD = acsp.CreateDecryptor();
                MemoryStream msD = new MemoryStream(RawBytes, 0, RawBytes.Length);
                CryptoStream csD = new CryptoStream(msD, ictD, CryptoStreamMode.Read);
                return (new StreamReader(csD)).ReadToEnd();
            }
        }

        private static TripleDESCryptoServiceProvider GetProvider(byte[] key)
        {
            TripleDESCryptoServiceProvider result = new TripleDESCryptoServiceProvider();
            result.Mode = CipherMode.CBC;
            result.Padding = PaddingMode.PKCS7;
            result.IV = new byte[] { 0, 0, 0, 0, 0, 0, 0, 0 };
            result.Key = key;
            return result;
        }

    }
4

3 に答える 3

4

AES キーは 128、192、または 256 ビットで、192 はめったに見られません。

トリプル DSE は通常 112 ビットですが、168 ビットにすることもできます。これはビット単位で指定されることに注意してください。トリプル DES では、各バイトにパリティ ビットがあり、したがって 7 データ ビットであると想定されます。通常、トリプル DES は、単一の DES エンコード、デコード、およびエンコードとデコードの両方に使用される 1 つのキー k1、k2、k1 でエンコードを実行することにより、互換モード (シングル DES と互換) で使用されます。したがって、8 バイト キー * 7 ビット * 2 = 112 です。デコード、エンコード、デコードが使用される場合があるため、これも問題になる可能性があります。

最初に正しいキーを取得します。AES から 3DES に変更しているため、キー サイズが異なるため、問題になる可能性があります。また、モードと IV が正しいことを確認してください。

最善の策は、キー、IV (存在する場合)、および暗号化関数の両側と両方のプラットフォームで 16 進数のデータをダンプすることです。これらを一致させるための最初の作業。次に、問題はbase64またはその他の操作に関係しています。

于 2009-12-09T01:18:29.870 に答える
0

.Net の crypto パッケージが暗号化の前にデータに追加するランダムな値に注意してください。記憶が正しければ、通常はデータの最初の 16 ビットです。

于 2009-12-09T03:06:46.920 に答える
0

これが機能するには、入力、キー、ソルト、およびアルゴリズムのすべてを両側で正確に一致させる必要があります。AesCryptoServiceProvider と TripleDesServiceProvider は異なる結果を生成し、kCCAlgorithmAES128 と kCCAlgorithm3DES は異なる結果を生成します。

于 2009-12-08T21:35:54.240 に答える