Reputation: 496
I am trying to encrypt a NSString using 3DES with CBC mode encryption on iOS.
Same encryption method is being used on ASP.NET as well and the encrypted string they are getting works with the webservice. The encrypted string for woodcraft554
obtained from .NET code is: 9SWzd+rlvu/tK5UZoCXt8Q==
.
.NET is using zero padding for encrytion. The code I am using is:
+(NSString*)new3DESwithoperand:(NSString*)plaintext encryptOrDecrypt:(CCOperation)encryptorDecrypt key:(NSString*)key initVec:(NSString*)initVec
{
NSData* data = [plaintext dataUsingEncoding:NSUTF8StringEncoding];
const void *vplainText = [data bytes];;
size_t plainTextBufferSize = [data length];
NSLog(@"%@, Length: %u",[data description],[data length]);
size_t bufferPtrSize = (plainTextBufferSize + kCCBlockSize3DES) & ~(kCCBlockSize3DES - 1);
NSLog(@"%zu, sizof of uint8_t: %zu",bufferPtrSize, sizeof(uint8_t));
size_t movedBytes = 0;
uint8_t *bufferPtr = malloc( bufferPtrSize * sizeof(uint8_t));
NSLog(@"%zu",sizeof(bufferPtr));
memset((void*)bufferPtr, 0x0, bufferPtrSize);
NSLog(@"%zu",sizeof(bufferPtr));
// memset((void *)initVec, 0x0, (size_t) sizeof(initVec));
const void * vkey = [[NSString base64DataFromString:key] bytes];
const void *vinitVec = [[NSString base64DataFromString:initVec] bytes];
NSLog(@"vinitvec: %@",[[NSString base64DataFromString:initVec] description]);
CCCryptorStatus ccStatus;
ccStatus = CCCrypt(encryptorDecrypt,
kCCAlgorithm3DES,
kCCOptionPKCS7Padding & kCCModeCBC,
vkey,
kCCKeySize3DES,
vinitVec,
vplainText,
plainTextBufferSize,
(void*)bufferPtr,
bufferPtrSize,
&movedBytes);
NSData* result = [NSData dataWithBytes:(const void*)bufferPtr length:(NSUInteger)movedBytes];
NSString* str = [NSString base64StringFromData:result length:result.length];
NSLog(@"%@",str);
return str;
}
I have compared vplainText
, vkey
and vinitVec
from objective-c code to that in .NET. They are same. The encrypted string I am getting is 9SWzd+rlvu8=
. I believe it's something to do with padding.
Here is equivalent .NET code they are using:
protected string EncryptCreditCard(string creditCard)
{
try
{
string ENCRYPTION_KEY = ConfigurationManager.AppSettings["ENCRYPTION_KEY"].ToString();
string ENCRYPTION_IV = ConfigurationManager.AppSettings["ENCRYPTION_IV"].ToString();
SymmetricAlgorithm sa = SymmetricAlgorithm.Create("TripleDES");
sa.Key = System.Convert.FromBase64String(ENCRYPTION_KEY);
sa.IV = System.Convert.FromBase64String(ENCRYPTION_IV);
sa.Padding = PaddingMode.Zeros;
byte[] inputByteArray = Encoding.ASCII.GetBytes(creditCard);
MemoryStream mS = new MemoryStream();
ICryptoTransform trans = sa.CreateEncryptor();
byte[] buf = new byte[2048];
CryptoStream cs = new CryptoStream(mS, trans, CryptoStreamMode.Write);
cs.Write(inputByteArray, 0, inputByteArray.Length);
cs.FlushFinalBlock();
return Convert.ToBase64String(mS.ToArray());
}
catch
{
return "";
}
}
How can I get a correct encrypted string in iOS ?
Upvotes: 2
Views: 4220
Reputation: 164
The issue is with "key" which is used for encryption. iOS uses a 24Byte key while Adnroid and .NET use 16Byte key.
Have posted a detailed solution for the same issue, which depicts key generation. Solution for different encryption value generated in iOS
Upvotes: 0
Reputation: 94058
By using zero padding. Your code clearly states kCCOptionPKCS7Padding
, which is not zero padding. The cipher text seems identical otherwise.
Note that you are better off using PaddingMode.PKCS7
in your .NET code. It adds some data in the odd case that your plain text is already a number of times the block size in size, but it is standardized and unpadding is not depending on the plain text value anymore.
Upvotes: 1