【发布时间】: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