Faz um tempo que necessitei trabalhar com calculo de "hash" e também com "assinatura digital". Para isso, tentei usar o "CAPICOM SDK" da Microsoft mas me deparei com problemas que até hoje eu não tinha encontrado uma solução.
1 - O primeiro problema que encontrei foi com o método "Hash" da classe "HashedData". Percebi que o calculo retornado não estava correto. Depois de pesquisar sobre o caso identifiquei que alterando o tipo do parâmetro do método "Hash" de "WideString" para "String", o problema foi resolvido.
Vejam como o Delphi mapeia o tipo do parâmetro quando fizemos a importação da capicom.dll:
----------------------------------------------
IHashedData = interface(IDispatch)
['{9F7F23E8-06F4-42E8-B965-5CBD044BF27F}']
function Get_Value: WideString; safecall;
function Get_Algorithm: CAPICOM_HASH_ALGORITHM; safecall;
procedure Set_Algorithm(pVal: CAPICOM_HASH_ALGORITHM); safecall;
procedure Hash(const newVal: WideString); safecall;
property Value: WideString read Get_Value;
property Algorithm: CAPICOM_HASH_ALGORITHM read Get_Algorithm write Set_Algorithm;
end;
----------------------------------------------
Agora, vejam a alteração que fiz na "CAPICOM_TLB.pas" para funcionar corretamente:
----------------------------------------------
IHashedData = interface(IDispatch)
['{9F7F23E8-06F4-42E8-B965-5CBD044BF27F}']
function Get_Value: WideString; safecall;
function Get_Algorithm: CAPICOM_HASH_ALGORITHM; safecall;
procedure Set_Algorithm(pVal: CAPICOM_HASH_ALGORITHM); safecall;
procedure Hash(const newVal: String); safecall;
property Value: WideString read Get_Value;
property Algorithm: CAPICOM_HASH_ALGORITHM read Get_Algorithm write Set_Algorithm;
end;
----------------------------------------------
2 - O segundo problema que encontrei foi com o método "Sign" da classe "SignedData". Percebi que a assinatura retornada não estava correta. Depois de pesquisar ainda muito mais que no primeiro caso identifiquei que alterando o tipo da propriedade "Content" de "WideString" para "String" e alterar a implementação do método "Set_Content", o problema foi resolvido.
Vejam como o Delphi mapeia o tipo da propriedade quando fizemos a importação da capicom.dll:
----------------------------------------------
ISignedData = interface(IDispatch)
['{AE9C454B-FC65-4C10-B130-CD9B45BA948B}']
procedure Set_Content(const pVal: WideString); safecall;
function Get_Content: WideString; safecall;
function Get_Signers: ISigners; safecall;
function Get_Certificates: ICertificates; safecall;
function Sign(const pSigner: ISigner; bDetached: WordBool; EncodingType: CAPICOM_ENCODING_TYPE): WideString; safecall;
function CoSign(const pSigner: ISigner; EncodingType: CAPICOM_ENCODING_TYPE): WideString; safecall;
procedure Verify(const SignedMessage: WideString; bDetached: WordBool;
VerifyFlag: CAPICOM_SIGNED_DATA_VERIFY_FLAG); safecall;
property Content: WideString read Get_Content write Set_Content;
property Signers: ISigners read Get_Signers;
property Certificates: ICertificates read Get_Certificates;
end;
----------------------------------------------
Agora, vejam a alteração que fiz na "CAPICOM_TLB.pas" para funcionar corretamente:
----------------------------------------------
ISignedData = interface(IDispatch)
['{AE9C454B-FC65-4C10-B130-CD9B45BA948B}']
procedure Set_Content(const pVal: String); safecall;
function Get_Content: String; safecall;
function Get_Signers: ISigners; safecall;
function Get_Certificates: ICertificates; safecall;
function Sign(const pSigner: ISigner; bDetached: WordBool; EncodingType: CAPICOM_ENCODING_TYPE): WideString; safecall;
function CoSign(const pSigner: ISigner; EncodingType: CAPICOM_ENCODING_TYPE): WideString; safecall;
procedure Verify(const SignedMessage: WideString; bDetached: WordBool;
VerifyFlag: CAPICOM_SIGNED_DATA_VERIFY_FLAG); safecall;
property Content: String read Get_Content write Set_Content;
property Signers: ISigners read Get_Signers;
property Certificates: ICertificates read Get_Certificates;
end;
----------------------------------------------
Vejam como o Delphi implementa o método "Set_Content" quando fizemos a importação da capicom.dll:
----------------------------------------------
procedure TSignedData.Set_Content(const pVal: WideString);
{ Warning: The property Content has a setter and a getter whose
types do not match. Delphi was unable to generate a property of
this sort and so is using a Variant as a passthrough. }
var
InterfaceVariant: OleVariant;
begin
InterfaceVariant := DefaultInterface;
InterfaceVariant.Content := pVal;
end;
----------------------------------------------
Agora, vejam a alteração que fiz na "CAPICOM_TLB.pas" para funcionar corretamente:
----------------------------------------------
procedure TSignedData.Set_Content(const pVal: WideString);
{ Warning: The property Content has a setter and a getter whose
types do not match. Delphi was unable to generate a property of
this sort and so is using a Variant as a passthrough. }
var
InterfaceVariant: ISignedData;
begin
InterfaceVariant := DefaultInterface;
InterfaceVariant.Content := pVal;
end;
----------------------------------------------
Em relação ao problema 1, tenho certeza de ter corrigido pois pude comparar o calculo do hash com outras ferramentas.
Em relação ao problema 2, o único parâmetro que tive até agora para comparar e decretar que o problema foi resolvido, foi fazer a verificação da assinatura gerada pelo CAPICOM em outro software, o Bry Signer (http://www.bry.com.br/). Como o Bry Signer já é utilizado em produção e vendido no mercado, é certo que a assinatura digital realizada por ele funciona corretamente, portanto, devido a uma assinatura digital gerada pela CAPICOM ser verificada e validada com sucesso através dele, concluí que o problema foi resolvido.
Quem passou pelo mesmo problema e aplicou uma solução diferente, por favor, deixe seu comentário.
Abraço!
10 de junho de 2013
10 de janeiro de 2013
SpeechMagic e SpeechMike
Na empresa onde trabalho, acabei de concluir a integração entre nosso software, que é construído com o Delphi e o software de reconhecimento de voz da Nuance: "SpeechMagic". Alem disso, também integrei o microfone da Philips: "SpeechMike". O editor usado na integração é o TRichEdit.
Quem representa e revende o "SpeechMagic" e o "SpeechMike" aqui no Brasil é a Macsym (www.macsym.com.br).
Quem tiver interesse, pode entrar em contato :)
Abraço a todos!
Quem representa e revende o "SpeechMagic" e o "SpeechMike" aqui no Brasil é a Macsym (www.macsym.com.br).
Quem tiver interesse, pode entrar em contato :)
Abraço a todos!
Marcadores:
ActiveX,
Delphi,
Ditado digital,
Nuance,
Philips,
Reconhecimento de voz,
SpeechMagic,
SpeechMike
Assinar:
Postagens (Atom)