EldoS | Feel safer!

Software components for data protection, secure storage and transfer

RSA Encryption with private key

Also by EldoS: Solid File System
A virtual file system that offers a feature-rich storage for application documents and data with built-in compression and encryption.
#4838
Posted: 02/01/2008 08:40:55
by Peet Terluin (Standard support level)
Joined: 06/08/2007
Posts: 19

Hello,

I'm currently working on an application that has to fill a signature field in a message.
This signature is build in a few steps.

Step 1: take a distinct part of the message, concatenate this with the timestamp from the
header and create a SHA-1 hash. With this there are no problems.

Step 2: The result of step 1 is then to be encrypted (using RSA encryption) using the private
key (1024 bit) of the sender’s certificate.

Step 3: The result of step 2 is encoded using Base64 encoding and the result of this is
the signature to be used.

My problem is step 2. How do I encrypt the byte-array that is the result of the hashing?
I've tried to find the solution on this forum and in the examples,
but I haven't succeeded so far. I hope you can help. And before you ask, I use SSLBlackbox
Client-server VCL for Delphi.

With regards,

Peet Terluin
#4839
Posted: 02/01/2008 09:01:25
by Eugene Mayevski (EldoS Corp.)

What you describe is called signing, not encryption.
It's possible to perform custom signing, but in order to do it right, you need to answer the following question: who and how will read and validate this signature? Is there any specification (document) or instructions regarding how the resulting signature should be formatted (binary data can also be formatted)? OR is it your application that will perform validation?

If you will perform validation as well, then the simpliest would be to use ElMessageSigner/ElMessageVerifier classes to perform PKCS#7 signing of the data. You can create the *detached* signature, which is made of a separate data body and signature (attached signature, on the other hand, is "wrapping" i.e. the result of signing includes both data and signature in one binary data block).

If you insist on doing everything on the low level, then you can use ElRSAPublicKeyCrypto class for RSA signing (remember that you need to call Sign) and use ElRSAPublicKeyMaterial to manage the keys.
For hashing you can use ElHashFunction class.


Sincerely yours
Eugene Mayevski
#4951
Posted: 02/11/2008 06:26:01
by Cees Lieshout (Standard support level)
Joined: 02/06/2008
Posts: 10

Currently trying to create a XML signing. As test I would also like to create the signature manually. I can't find the option/property detached or wrapping within the TElMessageSigner component. Can you explain how I can set the detached option?

Thanks,

Cees
#4952
Posted: 02/11/2008 06:47:52
by Eugene Mayevski (EldoS Corp.)

Did you check the Sign method description?


Sincerely yours
Eugene Mayevski
#4953
Posted: 02/11/2008 07:20:41
by Cees Lieshout (Standard support level)
Joined: 02/06/2008
Posts: 10

Apparently not, I found the lowlevel variant signdetached, but I see the optional detached parameter (now).

Thanks and excuse my ignorance
#4954
Posted: 02/11/2008 07:26:48
by Eugene Mayevski (EldoS Corp.)

ElMessageSigner doesn't have SignDetached method.


Sincerely yours
Eugene Mayevski
#4978
Posted: 02/13/2008 10:16:55
by Peet Terluin (Standard support level)
Joined: 06/08/2007
Posts: 19

Hello again,

I now have a nice working piece of code, inspired on the sample PKI/Primitives/SignDetached.

So far so good.

When I use a certificate loaded from a file (p12) it works fine.
However when I use the same certificate loaded from the Windows Certificate Storage
an exception occurs:
Project Tester.exe raised exception class EElWin32CryptoProviderError with message 'Unsupported hash algorithm (32767)'.

What causes this and can I do something about it?

With regards,

Peet Terluin
#4979
Posted: 02/13/2008 11:23:22
by Eugene Mayevski (EldoS Corp.)

Post your nice piece of code here, please.


Sincerely yours
Eugene Mayevski
#4989
Posted: 02/14/2008 04:57:12
by Peet Terluin (Standard support level)
Joined: 06/08/2007
Posts: 19

What a nice idea :)

Below are 3 procedures, the exception occurs somewhere while executing SignDetached, only
when the certificate is retrieved from windows certificate storage.

I can workaround this for now, but it seems a bit odd to me.

With regards,

Peet Terluin

// Get certificate from windows storage
function GetCertificate(CommonName: string; var Cert: TElX509Certificate): boolean; overload;
var WCS: TElWinCertStorage;
i: Integer;
begin
Result := False;
Cert := nil;
WCS := TElWinCertStorage.Create(nil);
WCS.Options := [csoStrictChainBuilding];
WCS.SystemStores.Add('My');
WCS.ReadOnly := True;

if CommonName <> '' then
begin
for i := 0 to WCS.Count - 1 do
begin
cert := TElX509Certificate.Create(nil);
cert.Assign(WCS.Certificates[i]);
if UpperCase(CommonName) = UpperCase(Cert.SubjectName.CommonName) then
begin
Result := True;
Break;
end;
cert.Free;
end;
end;
if not Result then
begin
cert.Free;
cert := nil;
end;

WCS.Destroy;
end;

// Get pfx-certificate from file
function GetCertificate(FileName, Password: string; var Cert: TElX509Certificate): boolean; overload;
var fs: TFileStream;
r: integer;
begin
GetCertificate := False;
try
cert := TElX509Certificate.Create(nil);
fs := TFileStream.Create(FileName, fmOpenRead);
r := cert.LoadFromStreamPFX(fs, PassWord);
fs.Destroy;
if r <> 0 then raise Exception.Create('Kan certificaat niet laden');
GetCertificate := True;
except
on e: Exception do
begin
FreeAndNil(cert);
MsgBox(e.Message);
end;
end;
end;

// Create signature
function TMainForm.CreateSignature(Cert: TElX509Certificate; AString: string; CertFromFile: boolean): string;
var
InputBuffer, SignBuffer: TMemoryStream;
S: string;
Crypto : TElRSAPublicKeyCrypto;
KeyMaterial : TELRSAKeyMaterial;
Cert := TElX509Certificate;
begin
if CertFromFile then
begin
if OpenFile(s, 'p12', 'Kies certificaat', True) then
begin
if not GetCertificate(s, 'ab1234', Cert) then
begin
MsgBox('Kan certificaat niet laden.');
exit;
end;
end;
end else
begin
if not GetCertificate(CertBox.Text, Cert) then
begin
MsgBox('Kan certificaat niet laden.');
exit;
end;
end;

// Step 1 : SHA1 AString;
S := sha1hash(AString, false);

// Step 2 : Doe RSA met private key van Cert op AString;
InputBuffer := TMemoryStream.Create;
InputBuffer.Write(S[1], Length(S));
InputBuffer.Position := 0;

SignBuffer := TMemoryStream.Create;
Crypto := TElRSAPublicKeyCrypto.Create();
Crypto.InputEncoding := pkeBinary;
Crypto.OutputEncoding := pkeBase64;
KeyMaterial := TELRSAKeyMaterial.Create;

KeyMaterial.Assign(Cert.Keymaterial);
Crypto.InputIsHash := True;

Crypto.KeyMaterial := KeyMaterial;

Crypto.SignDetached(InputBuffer, SignBuffer);

SetLength(s, SignBuffer.Size);
SignBuffer.Position := 0;
SignBuffer.Read(s[1], SignBuffer.Size);

CreateSignature := s;

InputBuffer.Free;
SignBuffer.Free;
Crypto.Free;
KeyMaterial.Free;
end;
#5013
Posted: 02/15/2008 02:58:51
by Ken Ivanov (EldoS Corp.)

You did not specify the hash algorithm being used. Please add the following line before doing the actual signing:

Crypto.HashAlgorithm := SB_ALGORITHM_DGST_SHA1;
Also by EldoS: BizCrypto
Components for BizTalk® and SQL Server® Integration Services that let you securely store and transfer information in your business automation solutions.

Reply

Statistics

Topic viewed 6930 times

Number of guests: 2, registered members: 0, in total hidden: 0




|

Back to top

As of July 15, 2016 EldoS Corporation will operate as a division of /n software inc. For more information, please read the announcement.

Got it!