2009-12-08 41 views
4

我需要加密iPhone上的一个字符串,并将其发送到一个.Net解密使用三重DES。我可以在iPhone和.Net上进行加密/解密,但在两种平台上我都得到了不同的结果。.Net和iPhone之间的三重DES互操作性?

我用的是同样的代码与.net和iPhone之间AES加密/解密在here

,我改变.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; 
     } 

    } 
+1

AES和TripleDES是完全不同的算法。 – overslacked 2009-12-08 21:29:40

+0

你是什么意思,“我在两个平台都得到不同的结果。“有什么不同?当正确使用加密时,给定的明文每次加密时都会产生不同的密文。这就是你所看到的吗? – erickson 2009-12-08 21:30:26

+0

我需要使用TripleDes代替AES。 如果我加密secret =”hello “key =”1234567890“我在iphone =”My8ZTBX07jU =“中获得,而在.net =”qpbpZnxzFqQ =“ – 2009-12-08 21:54:18

回答

4

AES密钥128,192或256位,192很少看到。

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

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

最好的办法是转储键,IV(如果有一个),并在对密码功能的两侧六角和两个平台上的数据。首先要让这些匹配。然后问题出现在base64或其他任何涉及的操作中。

+1

谢谢你这么多。我只需要将密钥转换为c字符串 – 2009-12-22 14:29:38

+0

如何解决该问题?我加密成功但解密失败。加密结果是:My8ZTBX05Mr – imcaptor 2010-11-25 14:23:43

0

你需要匹配所有的输入代码,密钥,盐和算法在这两个方面的工作。 AesCryptoServiceProvider和TripleDesServiceProvider会产生不同的结果,而kCCAlgorithmAES128和kCCAlgorithm3DES会产生不同的结果。

0

当心,NET的加密包将添加到您的数据加密之前,如果我没有记错它通常是数据的前16位的随机值。