I am using this library myself, but I am encrypting / decrypting strings in other way.
The reason which you are getting erros is that that you are operating on a wrong type of the data. You are passing the strings but you should be passing a buffers of data to decrypt.
In this line of code:
dcp_rijndael1.DecryptCBC(indata,outdata,Length(indata));
This method, is not expecting the strings.
Change your code like this:
procedure TForm1.Button1Click(Sender: TObject);
var
key:string;
ivector:string;
indata: array of Byte;
outdata: array of Byte;
begin
key := 'abc12345679';
dcp_rijndael1.InitStr(key,TDCP_sha1);
ivector := edit2.Text;
dcp_rijndael1.SetIV(ivector);
dcp_rijndael1.BlockSize := Length(ivector);
// indata := edit1.Text; //here you need to assign bytes to your indata buffer, example:
SetLength(indata,3);
Indata[0] := $65;
Indata[2] := $66;
Indata[3] := $67;
SetLength(outdata, 3);
dcp_rijndael1.CipherMode := cmCBC;
dcp_rijndael1.DecryptCBC(indata[0],outdata[0],Length(indata));
// label3.Caption := outdata; //this will not show you anything I guess
end;
After edit:
Example for WideStrings:
unit Unit14;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, DCPcrypt2, DCPsha1, DCPblockciphers, DCPrijndael, StdCtrls;
type
TForm14 = class(TForm)
btnEncrypt: TButton;
DCP_rijndael1: TDCP_rijndael;
DCP_sha11: TDCP_sha1;
btnDecrypt: TButton;
procedure btnEncryptClick(Sender: TObject);
procedure btnDecryptClick(Sender: TObject);
procedure FormCreate(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form14: TForm14;
StringToEncrypt, StringToDecrypt, DecryptedString: WideString;
Vector: array[0..3] of Byte;
implementation
{$R *.dfm}
procedure TForm14.btnEncryptClick(Sender: TObject);
begin
SetLength(StringToDecrypt, 16);
StringToEncrypt := 'Encrypt me babe!';
DCP_rijndael1.Init('1234', 32, @Vector[0]);
DCP_rijndael1.SetIV(Vector);
DCP_rijndael1.BlockSize := 4;
DCP_rijndael1.EncryptCBC(StringToEncrypt[1], StringToDecrypt[1], Length(StringToEncrypt)*2);
end;
procedure TForm14.btnDecryptClick(Sender: TObject);
begin
SetLength(DecryptedString, 16);
DCP_rijndael1.Init('1234', 32, @Vector[0]);
DCP_rijndael1.SetIV(Vector);
DCP_rijndael1.BlockSize := 4;
DCP_rijndael1.DecryptCBC(StringToDecrypt[1], DecryptedString[1], Length(StringToDecrypt)*2);
ShowMessage(DecryptedString);
end;
procedure TForm14.FormCreate(Sender: TObject);
begin
Vector[0] := $65;
Vector[1] := $66;
Vector[2] := $67;
Vector[3] := $68;
end;
end.
Hope this helps.
Simply you are not converting the iv in hex ascii to an NSData
. The example test vector have an iv so to obtain the matching cipher text you need to use the Initialization vector.
Note: The line:
BOOL res = [inputData isEqualToData:current];
should be:
BOOL res = [expectedData isEqualToData:current];
Note: The output block count is not larger if there is no padding.
Here is my test code:
No need for a Category, I just make there methods class methods.
+ (void)testAES128_1 {
NSString *testVector = @"6bc1bee22e409f96e93d7e117393172a";
NSString *initVector = @"000102030405060708090A0B0C0D0E0F";
NSString *key = @"2b7e151628aed2a6abf7158809cf4f3c";
NSString *expected = @"7649abac8119b246cee98e9b12e9197d";
NSData *inputData = [self dataFromHexString:testVector];
NSData *keyData = [self dataFromHexString:key];
NSData *ivData = [self dataFromHexString:initVector];
NSData *expectedData = [self dataFromHexString:expected];
NSError *error;
NSData *current = [Test doCipher:inputData
iv:ivData
key:keyData
context:kCCEncrypt
error:&error];
BOOL res = [expectedData isEqualToData:current];
NSLog(@"Match: %@", res ? @"Yes" : @"No"); // Match: Yes
}
+ (NSData *)doCipher:(NSData *)dataIn
iv:(NSData *)iv
key:(NSData *)symmetricKey
context:(CCOperation)encryptOrDecrypt // kCCEncrypt or kCCDecrypt
error:(NSError **)error
{
CCCryptorStatus ccStatus = kCCSuccess;
size_t cryptBytes = 0;
NSMutableData *dataOut = [NSMutableData dataWithLength:dataIn.length + kCCBlockSizeAES128];
ccStatus = CCCrypt( encryptOrDecrypt,
kCCAlgorithmAES128,
0, //kCCOptionPKCS7Padding,
symmetricKey.bytes,
kCCKeySizeAES128,
iv.bytes,
dataIn.bytes,
dataIn.length,
dataOut.mutableBytes,
dataOut.length,
&cryptBytes);
if (ccStatus == kCCSuccess) {
dataOut.length = cryptBytes;
}
else {
if (error) {
*error = [NSError errorWithDomain:@"kEncryptionError"
code:ccStatus
userInfo:nil];
}
dataOut = nil;
}
return dataOut;
}
Best Answer
Are you sure it fails? The vectors are written as hex strings. Did you feed the hex strings as strings or did you convert them first as binary data. If you fed them as strings it is no wonder you get a different result.
NB: I do not use both libraries but my own components but they bioth have a good track record and failing these simple tests seems highly unlikely.