Capicom и SHA1 - Помогите перевести код Java в Delphi - PullRequest
3 голосов
/ 22 июня 2011

У меня есть Java-приложение, которое подписывает строку с использованием сертификата.Он работает зашифровывая строку с помощью SHA1.Я пытаюсь перевести код на Delphi 2010, но я понятия не имею, как заставить его работать так же, как это делает java-приложение (используя sha1).До сих пор я нашел это:

Доступ к Delphi 7 в хранилище сертификатов Windows X509

Это работает, но не использует sha1, и я получаю другие результаты, когда яЗапустите приложение Java.

Java-код

 char[] pass = (char[]) null;
 PrivateKey key = (PrivateKey) getKeyStore().getKey(alias, pass);
 Certificate[] chain = getKeyStore().getCertificateChain(alias);
 CertStore certsAndCRLs = CertStore.getInstance("Collection", new CollectionCertStoreParameters(Arrays.asList(chain)), "BC");
 X509Certificate cert = (X509Certificate) chain[0];
 CMSSignedDataGenerator gen = new CMSSignedDataGenerator();
 gen.addSigner(key, cert, CMSSignedDataGenerator.DIGEST_SHA1);
 gen.addCertificatesAndCRLs(certsAndCRLs);
 CMSProcessable data = new CMSProcessableByteArray(conteudoParaAssinar);
 CMSSignedData signed = gen.generate(data, true, "SunMSCAPI");
 byte[] envHex = signed.getEncoded();
 CertInfo certInfo = new CertInfo();
 certInfo.Hash = new BigInteger(envHex).toString(16);
 return certInfo;

Delphi Code

var
  lSigner: TSigner;
  lSignedData: TSignedData;
  fs: TFileStream;
  qt: integer;
  ch: PChar;
  msg : WideString;
  content : string;
  cert: TCertificate;
begin
  cert := Self.GetCert;
  content := 'test';
  lSigner := TSigner.Create(self);
  lSigner.Certificate := cert.DefaultInterface;
  lSignedData := TSignedData.Create(self);
  lSignedData.content := content;
  msg := lSignedData.Sign(lSigner.DefaultInterface, false, CAPICOM_ENCODE_BASE64);
  lSignedData.Free;
  lSigner.Free;

РЕДАКТИРОВАТЬ

На основе Javaкод, я должен получить информацию о сертификате в двоичном формате, применить Sha1 к нему, а они преобразовать его в шестнадцатеричный?Это правильный порядок и то же самое, что делает код Java?Я вижу некоторые константы SHA1 в capicom tlb, а также хеш-класс, возможно, мне стоит использовать эти классы, но я не знаю, как.

Ответы [ 2 ]

3 голосов
/ 22 июня 2011

Мы используем DCPCrypt в некоторых приложениях delphi, которые взаимодействуют с нашим приложением Java Tomcat и могут получать SHA-256-совместимые хэши. Я подозреваю, что SHA1 также легко.

Вот пример

function Sha256FileStreamHash(fs : TFileStream): String;
var
    Hash: TDCP_sha256;
    Digest: array[0..31] of byte;  // RipeMD-160 produces a 160bit digest (20bytes)
    i: integer;
    s: string;
begin
  if fs <> nil then
  begin
    fs.Seek(0, soFromBeginning);
    Hash:= TDCP_sha256.Create(nil);          // create the hash
    try
      Hash.Init;                                   // initialize it
      Hash.UpdateStream(fs,fs.Size);       // hash the stream contents
      Hash.Final(Digest);                          // produce the digest
      s:= '';
      for i:= 0 to 31 do
        s:= s + IntToHex(Digest[i],2);
      Result:= s;                              // display the digest
    finally
      Hash.Free;
    end;
  end;
end;
0 голосов
/ 01 июля 2011

Во-первых, что заставляет вас думать, что вы не используете SHA-1?Я спрашиваю, потому что функция подписи CAPICOM работает только с подписью SHA-1.

Во-вторых, откуда вы знаете, что получаете другой результат?Вы пытались подтвердить ответ?Если да, то с помощью чего?

В-третьих, есть что-то, что вы ДОЛЖНЫ знать о CAPICOM: свойство content является самой широкой строкой.Это имеет различные последствия, в том числе тот факт, что весь контент будет дополнен до 16 бит.Если ваши входные данные имеют другой размер, вы получите другой результат.

На основе кода Java, если я получу информацию сертификата в двоичном формате, примените к нему sha1, а затем преобразуйте егозаговорить?

Нет.Вы получаете интерфейс для экземпляра объекта ICertificate (или, более вероятно, ICertificate2), и вы просто используете его напрямую.Если у вас есть версия сертификата в кодировке B64, вы можете создать новый экземпляр ICertificate, а затем вызвать метод ICertificate.Import.Хэш самого сертификата используется только подписывающим органом для подписания этого конкретного сертификата.

Алгоритм хеширования фактически используется во время процесса подписи данных: библиотека считывает данные, создает хэш этих данных (используя SHA-1 в случае CAPICOM), а затем цифровой подписью этого значения хеш-функции.Это сокращение необходимо, потому что подписывание всего блока данных будет слишком медленным, и, таким образом, вам придется переносить хеш, только если вы используете аппаратную криптосистему.

Этоправильный порядок и то же самое, что делает код Java?

Да и нет.Java-код выполняет все необходимые шаги в явных деталях, чего вы не имеете (и на самом деле не можете) делать с CAPICOM.Это должно привести к совместимому результату.

У него также есть дополнительный шаг, не связанный с самой подписью: я не уверен, что он делает, потому что кажется, что он создает фиктивные данные сертификата и хранит SHA-1 хэш-значение подписанного сообщения CMS и возврат полученного экземпляра.Я полагаю, что Java-разработчик нашел способ передать значение хеша вызывающей стороне.

Я вижу некоторые константы SHA1 в capicom tlb, а также хеш-класс, возможно, мне следуетиспользовать эти классы, но я не знаю, как.

Класс HashedData используется для (неожиданности) хеш-данных.Он имеет то же ограничение, что и Signeddata, то есть он работает только с широкими строками, поэтому совместимость с другими платформами в лучшем случае хитрая.

Последнее замечание: Windows предлагает доступ к гораздо более полным криптографическим функциям через группу функций CAPI.CAPICOM - это только интерфейс к этой библиотеке, который используется (в основном) на языке сценариев (JavaScript на веб-страницах, VB и т. Д.).Вы должны сделать себе одолжение и попробовать использовать его вместо CAPICOM, потому что есть большая вероятность, что вы столкнетесь с чем-то, что вы просто не можете сделать должным образом, используя CAPICOM.На этом этапе вам придется переписать часть для всего вашего приложения, используя CAPI (или другую библиотеку).Поэтому сэкономьте время и пропустите CAPICOM, если у вас нет необходимости его использовать.

...