CryptoSys PKI Pro Manual

SIG_SignData

Compute a signature value over data in a byte array.

VBA/VB6 Syntax

Public Declare Function SIG_SignData Lib "diCrPKI.dll" (ByVal strOutput As String, ByVal nOutChars As Long, ByRef lpData As Byte, ByVal nDataLen As Long, ByVal strKeyFile As String, ByVal strPassword As String, ByVal strAlgName As String, ByVal nOptions As Long) As Long

nRet = SIG_SignData(strOutput, nOutChars, lpData(0), nDataLen, strKeyFile, strPassword, strAlgName, nOptions)

C/C++ Syntax

long __stdcall SIG_SignData(char *szOutput, long nOutChars, const unsigned char *lpData, long nDataLen, const char *szKeyFile, const char *szPassword, const char *szAlgName, long nOptions);

Parameters

szOutput
[out] string of sufficient length to receive the output.
nOutChars
[in] specifying the maximum number of characters to be received.
lpData
[in] byte array containing the input data to be signed.
nDataLen
[in] specifying the length of the input data in bytes.
szKeyFile
[in] specifying the name of the private key file (or a string containing the key in PEM format, or a valid internal private key string).
szPassword
[in] containing the password for the private key, or "" if not required.
szAlgName
[in] specifying the signature algorithm (case insensitive):
"sha1WithRSAEncryption" (default - CAUTION)
"sha224WithRSAEncryption"
"sha256WithRSAEncryption" [minimum recommended]
"sha384WithRSAEncryption"
"sha512WithRSAEncryption"
"md5WithRSAEncryption" [for legacy applications - not recommended for new implementations]
"ecdsaWithSHA1"
"ecdsaWithSHA224"
"ecdsaWithSHA256"
"ecdsaWithSHA384"
"ecdsaWithSHA512"
"RSA-PSS-SHA1"
"RSA-PSS-SHA224"
"RSA-PSS-SHA256"
"RSA-PSS-SHA384"
"RSA-PSS-SHA512"
"Ed25519" [New in v20.0] (see Remarks)
"Ed448" [New in v22.0] (see Remarks)
or "" to use the signature algorithm flag in nOptions, see Specifying the signature algorithm in a SIG_ function.
nOptions
[in] Zero (0) for defaults.
Add the bitflag:
To change the format of the output (default base64 encoded), add one of:
  • PKI_ENCODE_BASE64URL to encode the output in the URL-safe "base64url" encoding of [RFC4648]; or
  • PKI_ENCODE_HEX to encode the output in hexadecimal (base16) encoding
Options for ECDSA signatures only:
  • PKI_SIG_DETERMINISTIC to use the deterministic digital signature generation procedure of [RFC6979] for ECDSA signatures (default=random k)
  • PKI_SIG_ASN1DER to form the signature value as a DER-encoded ASN.1 structure (as used by Bitcoin); (default=simple concatenation r||s)
Options for RSA-PSS signatures only: [New in v12.0] (see RSA signature and encryption schemes)
Add one of the following to specify the salt length:
  • PKI_PSS_SALTLEN_HLEN (0) to set the salt length to hLen, the length of the output of the hash function (default).
  • PKI_PSS_SALTLEN_MAX to set the salt length to the maximum possible (OpenSSL does this by default)
  • PKI_PSS_SALTLEN_20 to set the salt length to be exactly 20 bytes regardless of the hash algorithm
  • PKI_PSS_SALTLEN_ZERO to set the salt length to be zero
and, optionally, add:-
  • PKI_MGF_MGF1SHA1 to force the MGF hash function to be SHA-1 (default = same as signature hash algorithm)

Returns (VBA/C)

If successful, the return value is the number of characters in or required for the output string; otherwise it returns a negative error code.

VBA Wrapper Syntax

Public Function sigSignData (lpData() As Byte, szKeyFile As String, szPassword As String, szAlgName As String, Optional nOptions As Long = 0) As String

.NET Equivalent

Sig.SignData Method
Sig.SignDigest Method

static Sig.sign_digest(digest, keyfile, password, alg, opts=Opts.DEFAULT, encoding=Encoding.DEFAULT)
static Sig.sign_digest(digest, keyfile, password, alg, opts=Opts.DEFAULT, encoding=Encoding.DEFAULT)

C++ (STL) Equivalent

static std::string dipki::Sig::SignData (const bvec_t &data, const std::string &keyFileOrString, const std::string &password="", Alg alg=Alg::Default, Encoding encoding=Encoding::Base64, SigOptions opts=SigOptions::None)
static Sig.sign_digest(digest, keyfile, password, alg, opts=Opts.DEFAULT, encoding=Encoding.DEFAULT)

Python Equivalent

static Sig.sign_data(data, keyfile, password, alg, opts=Opts.DEFAULT, encoding=Encoding.DEFAULT)
static Sig.sign_digest(digest, keyfile, password, alg, opts=Opts.DEFAULT, encoding=Encoding.DEFAULT)

Remarks

For the "raw" VBA/C function, the user must allocate an output string buffer szOutput of the required length. Specify a zero nOutChars or an empty string for szOutput to find the required length. ANSI C users must add one to this value when allocating memory.

Computes the signature value over the input data (or its digest value) using the private key provided. The default output is a continuous string of base64 characters suitable to include in the <SignatureValue> node of an XML-DSIG document. Alternative output encodings (base64url and hex) can be specified using the PKI_ENCODE_ options.

The PKI_SIG_USEDIGEST option cannot be used with Ed25519 or Ed448. The data to be signed must be passed in toto to the signature function. All options except the PKI_ENCODE_ options are ignored for the Ed25519 and Ed448 algorithms.

Example (VBA core function)

Dim strSignature As String
Dim nChars As Long
Dim strData As String
Dim abData() As Byte
Dim nDataLen As Long
Dim strKeyFile As String
Dim strPassword As String
Dim strAlgName As String

' 1) Input data = three-character ASCII string "abc"
strData = "abc"
strKeyFile = "AlicePrivRSASign.p8e"
strPassword = "password" ' CAUTION: do not hard-code passwords!
strAlgName = "sha1WithRSAEncryption"

' Convert ASCII string to byte array
abData = StrConv(strData, vbFromUnicode)
nDataLen = Len(strData)
' Find required length of output string
nChars = SIG_SignData("", 0, abData(0), nDataLen, strKeyFile, strPassword, _
  strAlgName, 0)
Debug.Print "SIG_SignData returns " & nChars & " (expected >0)"
' Allocate memory for output string
strSignature = String(nChars, " ")
nChars = SIG_SignData(strSignature, Len(strSignature), abData(0), nDataLen, _
  strKeyFile, strPassword, strAlgName, 0)
' Output base64 signature value
Debug.Print "SIG=" & strSignature

' 2) Use digest value instead of original data
' Convert known value of SHA-1("abc") in hex to an array of bytes
abData = cnvBytesFromHexStr("a9993e364706816aba3e25717850c26c9cd0d89d")
nDataLen = PKI_SHA1_BYTES
' Find required length of output string
nChars = SIG_SignData("", 0, abData(0), nDataLen, strKeyFile, strPassword, _
  strAlgName, PKI_SIG_USEDIGEST)
Debug.Print "SIG_SignData returns " & nChars & " (expected >0)"
' Allocate memory for output string
strSignature = String(nChars, " ")
nChars = SIG_SignData(strSignature, Len(strSignature), abData(0), nDataLen, _
  strKeyFile, strPassword, strAlgName, PKI_SIG_USEDIGEST)
' Output base64 signature value
Debug.Print "SIG=" & strSignature

This uses Alice's encrypted private key to sign the ASCII string "abc" using both the original string data (converted to a byte array) and its digest value. The output should be

SIG_SignData returns 172 (expected >0)
SIG=YK1aePtKQDDsVCyJdM0V9VOE6DZVTO3Z ... AmHH6QIsDZ8R8=
SIG_SignData returns 172 (expected >0)
SIG=YK1aePtKQDDsVCyJdM0V9VOE6DZVTO3Z ... AmHH6QIsDZ8R8=

The following example uses an elliptic curve key to produce an ECDSA signature in hex form using the "Deterministic" algorithm from [RFC6979]

Dim nChars As Long
Dim nBits As Long
Dim strIntKey As String
Dim strHexKey As String
Dim strCurveName As String
Dim strSignature As String
Dim strData As String
Dim abData() As Byte
Dim nDataLen As Long
Dim strAlgName As String

' Ref: [RFC6979] "Deterministic Usage of the DSA and ECDSA"
' A.2.3.  ECDSA, 192 Bits (Prime Field)
  
' 1. READ IN PRIVATE KEY IN (HEX,CURVENAME) FORMAT
strHexKey = "6FAB034934E4C0FC9AE67F5B5659A9D7D1FEFD187EE09FD4"
strCurveName = "P-192"
Debug.Print "KEYHEX: " & strHexKey
Debug.Print "CURVE: " & strCurveName
' Find required length of internal key string
nChars = ECC_ReadKeyByCurve("", 0, strHexKey, strCurveName, 0)
Debug.Print "ECC_ReadKeyByCurve returns " & nChars & " (expected +ve)"
' Dimension the string to receive output
strIntKey = String(nChars, " ")
' Read into internal key string
nChars = ECC_ReadKeyByCurve(strIntKey, Len(strIntKey), strHexKey, strCurveName, 0)
'Debug.Print "INTKEY: " & strIntKey
' Check we got the bitlength we expected
nBits = ECC_QueryKey("", 0, strIntKey, "keyBits", 0)
Debug.Print "NBITS=" & nBits

' 2. PREPARE INPUT DATA AS AN ARRAY OF BYTES
strData = "test"
strAlgName = "ecdsaWithSHA1"
' Convert ASCII string to byte array
abData = StrConv(strData, vbFromUnicode)
nDataLen = Len(strData)
  
'3. SIGN IT USING DETERMINISTIC ALGORITHM FROM [RFC6979]
' Find required length of output string
nChars = SIG_SignData("", 0, _
    abData(0), nDataLen, strIntKey, "", _
    strAlgName, PKI_SIG_DETERMINISTIC Or PKI_ENCODE_HEX)
Debug.Print "SIG_SignData returns " & nChars & " (expected >0)"
' Allocate memory for output string
strSignature = String(nChars, " ")
nChars = SIG_SignData(strSignature, Len(strSignature), _
    abData(0), nDataLen, strIntKey, "", _
    strAlgName, PKI_SIG_DETERMINISTIC Or PKI_ENCODE_HEX)

' Output hex signature value
Debug.Print "SIG=" & strSignature
KEYHEX: 6FAB034934E4C0FC9AE67F5B5659A9D7D1FEFD187EE09FD4
CURVE: P-192
ECC_ReadKeyByCurve returns 164 (expected +ve)
NBITS=192
SIG_SignData returns 96 (expected >0)
SIG=0f2141a0ebbc44d2e1af90a50ebcfce5e197b3b7d4de036deb18bc9e1f3d7387500cb99cf5f7c157070a8961e38700b7

Example (VBA wrapper function)

Dim lpData() As Byte
Dim strSig As String
lpData = StrConv("abc", vbFromUnicode)
strSig = sigSignData(lpData, "AlicePrivRSASign.p8e", "password", "sha1WithRSAEncryption")
Debug.Print "SIG=" & strSig
Debug.Print "OK =" & "YK1aePtKQDDsVCyJdM0V9VOE6DZVTO3Z ... AmHH6QIsDZ8R8="

See Also

SIG_SignFile

[Contents] [Index]

[PREV: RSA_ToXMLStringEx...]   [Contents]   [Index]   
   [NEXT: SIG_SignFile...]

Copyright © 2004-23 D.I. Management Services Pty Ltd. All rights reserved. Generated 2023-10-22T11:11:11Z.