EldoS | Feel safer!

Software components for data protection, secure storage and transfer

Private key and windows certificates

Also by EldoS: Rethync
The cross-platform framework that simplifies synchronizing data between mobile and desktop applications and servers and cloud storages
#22302
Posted: 11/01/2012 08:04:29
by Ernesto Alconada (Basic support level)
Joined: 11/01/2012
Posts: 25

I need use a windows certificate that has a private key, but when i use the certificate in
Code
FCAdESProcessor.CreateEPES(Cert,'2.16.724.1.3.1.1.2.1.8',SB_CERT_ALGORITHM_SHA1_RSA_ENCRYPTION,'7SxX3erFuH31TvAw9LZ70N7p1vA=');
i get an error "Private key not found". How could i load its private key with the certificate?
#22303
Posted: 11/01/2012 08:09:02
by Eugene Mayevski (EldoS Corp.)

Where and how do you set the value of Cert? If you get it from TElWinCertStorage, the certificate accesses the private key stored in Windows certificate storage (given that the private key IS there).


Sincerely yours
Eugene Mayevski
#22306
Posted: 11/01/2012 08:43:53
by Ernesto Alconada (Basic support level)
Joined: 11/01/2012
Posts: 25

Quote
Eugene Mayevski wrote:
Where and how do you set the value of Cert? If you get it from TElWinCertStorage, the certificate accesses the private key stored in Windows certificate storage (given that the private key IS there).
Eugene Mayevski,

The way i set the value of Cert is:

Cert := TElX509Certificate.Create(nil);
try
with TElWinCertStorage.Create(nil) do
try
SystemStores.Add('MY');
Cert:=Certificates[ComboCertificados.ItemIndex];
finally
Free;
end;

The code i use to load the combobox "ComboCertificados" is:

with TElWinCertStorage.Create(nil) do
try
SystemStores.Add('MY');
C:=0;
while C<Count do
begin
ComboCertificados.Items.Add(GetCertDisplayName(Certificates[C]));
Inc©
end;
finally
Free;
end;

where GetCertDisplayName is a function, from one of your samples, that returns the name of certificate.
#22308
Posted: 11/01/2012 08:52:47
by Vsevolod Ievgiienko (EldoS Corp.)

Hello.

Try to Free an instance of TElWinCertStorage after a certificate is been used.

Please use a "code" tag for you code listings.
#22309
Posted: 11/01/2012 10:06:07
by Ernesto Alconada (Basic support level)
Joined: 11/01/2012
Posts: 25

Quote
Vsevolod Ievgiienko wrote:
Hello.

Try to Free an instance of TElWinCertStorage after a certificate is been used.

Please use a "code" tag for you code listings.
Vsevolod Ievgiienko,

I free it, and still says "no private key". Anyway, when I use the certificate, for example, in Internet Explorer, I have to enter a password. How could I enter a password to use a certificate with TElX509Certificate class? Thanks
#22310
Posted: 11/01/2012 10:37:24
by Vsevolod Ievgiienko (EldoS Corp.)

A password prompt window will be displayed by Windows in case when certificate is stored in Windows storage. Could you post here a full source code so it will become more clear why the problem appears.
#22311
Posted: 11/01/2012 11:05:20
by Ernesto Alconada (Basic support level)
Joined: 11/01/2012
Posts: 25

Quote
Vsevolod Ievgiienko wrote:
A password prompt window will be displayed by Windows in case when certificate is stored in Windows storage. Could you post here a full source code so it will become more clear why the problem appears.


Here you have the source code, is a modification of the .pas of one of your samples (CADES). I need to use the signature CADES-EPES, and this code working, to get a license of PKIBlackBox package. Thank you.


[ Download ]
#22312
Posted: 11/01/2012 11:10:43
by Vsevolod Ievgiienko (EldoS Corp.)

You didn't change the code as I suggested above:

Code
...
  // loading a certificate
  Cert := TElX509Certificate.Create(nil);
  try
    with TElWinCertStorage.Create(nil) do
    try
      SystemStores.Add('MY');
      Cert:=Certificates[ComboCertificados.ItemIndex];
    finally
      Free;
    end;


You should rewrite it this way:
Code
...
Storage := TElWinCertStorage.Create(nil);
try
  SystemStores.Add('MY');
  Cert:=Certificates[ComboCertificados.ItemIndex];
  // use Cert here to create a signature
  // you don't need to Free it as TElWinCertStorage will do this
finally
  Storage.Free;
end;
#22314
Posted: 11/01/2012 12:03:40
by Ken Ivanov (EldoS Corp.)

Ernesto,

Besides, it is a good idea to check whether the certificate has a corresponding private key at all by checking its PrivateKeyExists property.
#22315
Posted: 11/01/2012 15:15:06
by Ernesto Alconada (Basic support level)
Joined: 11/01/2012
Posts: 25

Vsevolod Ievgiienko,

I change the code as you say. But, now, i get an access violation at FCAdESProcessor.CreateEPES(Cert,'2.16.724.1.3.1.1.2.1.8',SB_CERT_ALGORITHM_SHA1_RSA_ENCRYPTION,'7SxX3erFuH31TvAw9LZ70N7p1vA=');

Too, could you help me about the property "TElCAdESSignatureProcessor.TrustedCertificates"?

A little more, and i will get it!

Thank you

Code
var
  Cert : TElX509Certificate;
  SourceStream, CMSStream : TFileStream;
  CMS : TElSignedCMSMessage;
  Sig : TElCMSSignature;
  SC:TStringList;
  Storage:TElWinCertStorage;
begin
  // loading a certificate
  Cert := TElX509Certificate.Create(nil);
  try
    Storage:=TElWinCertStorage.Create(nil);
    with Storage do
    try
      SystemStores.Add('MY');
      Cert:=Certificates[ComboCertificados.ItemIndex];
      // opening source file
      SourceStream := TFileStream.Create(editSource.Text, fmOpenRead or fmShareDenyWrite);
      try
        // creating a CMS and a signature object
        CMS := TElSignedCMSMessage.Create(nil);
        try
          CMS.CreateNew(SourceStream, 0, SourceStream.Size);
          Sig := CMS.Signatures[CMS.AddSignature()];

          // binding signature to CAdES processor
          FCAdESProcessor.Signature := Sig;

          // configuring CAdES processor
          FCAdESProcessor.ForceSigningCertificateV2 := true;
          FCAdESProcessor.IgnoreChainValidationErrors := true;
          FCAdESProcessor.OfflineMode := false;

          // creating signature of the specified level
          ClearLog;
          try
            FCAdESProcessor.CreateEPES(Cert,'2.16.724.1.3.1.1.2.1.8',SB_CERT_ALGORITHM_SHA1_RSA_ENCRYPTION,'7SxX3erFuH31TvAw9LZ70N7p1vA=');
            MessageDlg('Firmado correcto', mtInformation, [mbOk], 0);

            // saving the CMS
            if SaveDialog.Execute then
            begin
              CMSStream := TFileStream.Create(SaveDialog.Filename, fmCreate);
              try
                CMS.Save(CMSStream);
              finally
                FreeAndNil(CMSStream);
              end;
            end;
          except
            on E : Exception do
              MessageDlg('Firmado fallido (' + E.Message + '). Por favor lea el log para detalles', mtError, [mbOk], 0);
          end;

          // showing log window
          if Length(FLog.Text) > 0 then
            frmLog.Init(FLog.Text)
          else
            frmLog.Init('Log is empty');
          frmLog.ShowModal;
        finally
          FreeAndNil(CMS);
        end;
      finally
        FreeAndNil(SourceStream);
      end;
    finally
      FreeAndNil(Cert);
    end;
  finally
    FreeAndNil(Storage);
  end;
Also by EldoS: CallbackProcess
A component to control process creation and termination in Windows and .NET applications.

Reply

Statistics

Topic viewed 3289 times

Number of guests: 1, 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!