【问题标题】:Triple DES interoperability between .Net and iPhone?.Net 和 iPhone 之间的三重 DES 互操作性?
【发布时间】:2010-12-24 14:32:18
【问题描述】:

我需要在 iPhone 上加密一个字符串并将其发送到 .Net 以使用 Triple DES 进行解密。我能够在 iPhone 和 .Net 上加密/解密,但在这两个平台上我得到不同的结果。

我在here 中使用与 .Net 和 iPhone 之间的 AES 加密/解密相同的代码

我唯一改变 .net 的是加密算法,所以在它说 AesCryptoServiceProvider 的地方,我放了 TripleDesServiceProvider

在 .net 中,我唯一改变的是加密算法,所以在上面写着 kCCAlgorithmAES128 的地方,我输入了 kCCAlgorithm3DES

我错过了什么?

[更新]

感谢您的回复。

如果我留在同一个平台上,我可以毫无问题地加密/解密,但如果我在 iPhone 中加密并在 .net 中解密,则会出现问题,因为在每个平台上使用相同的输入会产生不同的结果。

正如 Overslacked 所说,我认为问题与盐有关,但我找不到该算法在每个平台上使用的任何 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;
        }

    }

【问题讨论】:

  • AES 和 TripleDES 是完全不同的算法。
  • 你是什么意思,“我在两个平台上得到不同的结果。”有什么不同吗?正确使用加密时,给定的明文每次加密时应该产生不同的密文。这是你看到的吗?
  • 我需要使用 TripleDes 而不是 AES。如果我加密 secret="hello" key="1234567890" 我进入 iphone="My8ZTBX07jU=" 和 .net="qpbpZnxzFqQ="
  • 加密中没有“盐”,但可能是 IV(初始化向量),具体取决于模式。欧洲央行没有 iv。
  • 你需要把问题分开。首先让加密使用相同的 24 字节密钥。该代码正在对字符串转换和填充进行假设。只需使用 char key[] = "111111111111111111111111";两侧。运送 base64 的东西。十六进制转储密钥和数据输入和数据输出。当你有这个工作添加回其他东西。

标签: .net iphone security cryptography 3des


【解决方案1】:

您需要完全匹配双方的所有输入、键、盐和算法才能使其正常工作。 AesCryptoServiceProvider 和 TripleDesServiceProvider 会产生不同的结果,而 kCCAlgorithmAES128 和 kCCAlgorithm3DES 会产生不同的结果。

【讨论】:

    【解决方案2】:

    AES 密钥为 128、192 或 256 位,192 很少见。

    三重 DSE 通常是 112 位,但也可以是 168 位。请注意,这是以位为单位指定的。三重 DES 期望每个字节有一个奇偶校验位,因此有 7 个数据位。通常,Triple DES 用于兼容模式(与 Single DES 兼容),通过使用一个用于编码和解码的密钥 k1、k2、k1 执行单个 DES 编码、解码和编码。因此 8 字节密钥 * 7 位 * 2 = 112。有时会使用解码、编码、解码,所以这也可能是个问题。

    首先获取正确的密钥。由于您要从 AES 更改为 3DES,因此密钥大小会有所不同,这可能是个问题。还要确保模式和 IV 正确。

    最好的办法是在加密函数的两侧和两个平台上以十六进制转储密钥、IV(如果有)和数据。首先要让这些匹配。那么问题就出在 base64 或涉及其他任何操作。

    【讨论】:

    • 非常感谢。我只需要将密钥转换为 c 字符串
    • 如何解决这个问题?我加密成功但解密失败。加密结果为:My8ZTBX05Mr
    【解决方案3】:

    请注意 .Net 的加密包在加密之前会添加到您的数据中的随机值,如果我没记错的话,它通常是前 16 位数据。

    【讨论】:

      猜你喜欢
      • 2010-10-07
      • 1970-01-01
      • 1970-01-01
      • 2011-03-16
      • 2013-06-08
      • 1970-01-01
      • 2014-05-04
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多