Attribute VB_Name = "basTestChileSign" ' $Id: basTestChileSign $ ' $Date: 2013-09-04 13:23 $ ' $Author: dai $ ' This module uses functions from the CryptoSys (tm) PKI Toolkit available from ' <https://cryptosys.net/pki/>. ' Include the module `basCrPKI' in your project. ' *************************** COPYRIGHT NOTICE ****************************** ' This code was originally written by David Ireland and is copyright ' (C) 2013 DI Management Services Pty Ltd <https://di-mgt.com.au>. ' Provided "as is". No warranties. Use at your own risk. You must make your ' own assessment of its accuracy and suitability for your own purposes. ' It is not to be altered or distributed, except as part of an application. ' You are free to use it in any application, provided this copyright notice ' is left unchanged. ' ************************ END OF COPYRIGHT NOTICE ************************** Option Explicit ' To create a signature ' 1. Compute the message digest value of the canonicalized data-to-be-signed. ' 2. Compose a <SignedInfo> XML fragment, in canonicalized form, which contains the message digest value from step 1. ' 3. Compute the message digest of the canonicalized <SignedInfo> element. ' 4. Sign this message digest using your private key to produce a signature value. ' For steps 1 to 3, use MakeDigestValueOfSignedInfo ' <http://cryptosys.net/pki/basTestChile.html#MakeDigestValueOfSignedInfo> ' For step 4, use SignSignedInfo below Public Function Test_SignSignedInfo() Dim strDigestHex As String Dim strPrikeyFile As String Dim strPassword As String Dim strSigValue64 As String ' OUR TEST INPUT DATA: ' The digest value we made earlier... strDigestHex = "353CABFE369AAD9BEA21F5FA06CB367960FFB7D4" ' We do not have the signing key used in the SII example. We use a test private key... strPrikeyFile = "AlicePrivRSASign.key" ' CAUTION: do not hardcode password in production code... strPassword = "password" Debug.Print "SHA-1 message digest of <SignedInfo> = " & strDigestHex strSigValue64 = SignSignedInfo(strDigestHex, strPrikeyFile, strPassword) Debug.Print "SignatureValue=" & strSigValue64 ' Clean up password strPassword = WIPE_String(strPassword, Len(strPassword)) End Function Public Function SignSignedInfo(strDigestHex As String, strPrikeyFile As String, strPassword As String) As String ' INPUT: SHA-1 digest of canonicalized <SignedInfo> element in HEX format ' Signer's encrypted private key file ' Password for private key file ' OUTPUT: Signature value in base64 form Dim abDigest() As Byte Dim strPrivateKey As String Dim abBlock() As Byte Dim nkLen As Long Dim ndLen As Long Dim nRet As Long Dim strSigVal64 As String ' Read in private key from key file strPrivateKey = rsaReadPrivateKey(strPrikeyFile, strPassword) If Len(strPrivateKey) = 0 Then MsgBox "Error: Cannot read RSA key file '" & strPrikeyFile & "'", vbCritical Exit Function End If ' Get length of key in bytes (expecting 128) nkLen = RSA_KeyBytes(strPrivateKey) Debug.Print " " & "Key is " & nkLen & " bytes long" ' Convert digest value from Hex form to Byte array ' -- expecting exactly 20 bytes ndLen = PKI_SHA1_BYTES If (Len(strDigestHex) <> ndLen * 2) Then MsgBox "Error: expecting exactly 40 hex chars in strDigestHex", vbCritical Exit Function End If ReDim abDigest(ndLen - 1) nRet = CNV_BytesFromHexStr(abDigest(0), ndLen, strDigestHex) Debug.Print " " & "Digest=" & cnvHexStrFromBytes(abDigest) ' Encode digest value for signature ReDim abBlock(nkLen - 1) nRet = RSA_EncodeMsg(abBlock(0), nkLen, abDigest(0), ndLen, PKI_EMSIG_PKCSV1_5 + PKI_EMSIG_DIGESTONLY) Debug.Print " " & "RSA_EncodeMsg returns " & nRet & " (expected 0)" Debug.Print " " & "EM: " & cnvHexStrFromBytes(abBlock) ' Sign using RSA private key nRet = RSA_RawPrivate(abBlock(0), nkLen, strPrivateKey, 0) Debug.Print " " & "SG: " & cnvHexStrFromBytes(abBlock) ' Convert the byte array to base64 encoding strSigVal64 = cnvB64StrFromBytes(abBlock) ' Return base64-encoded signature value SignSignedInfo = strSigVal64 End Function