CryptoSys PKI Pro Manual

RSA_DecodeMsg

Decodes an EME or EMSA encoded message block according to PKCS#1 (EME = Encoding Method for Encryption, EMSA = Encoding Method for Signature with Appendix).

VBA/VB6 Syntax

Public Declare Function RSA_DecodeMsg Lib "diCrPKI.dll" (ByRef lpOutput As Byte, ByVal nOutChars As Long, ByRef lpInput As Byte, ByVal nInputLen As Long, ByVal nOptions As Long) As Long

nRet = RSA_DecodeMsg(lpOutput(0), nOutputLen, lpInput(0), nInputLen, nOptions)

C/C++ Syntax

long __stdcall RSA_DecodeMsg(unsigned char *lpOutput, long nOutBytes, const unsigned char *lpInput, long nInputLen, long nOptions);

Parameters

lpOutput
[out] array to receive the decoded output.
nOutBytes
[in] specifying the maximum length of the output array.
lpInput
[in] array containing the data to be decoded.
nInputLen
[in] specifying the number of bytes in the input.
nOptions
[in] option flags. Include one of the following:-
PKI_EME_PKCSV1_5 (0) to decode an 'Encoded Message for Encryption' block using PKCS#1 v1.5 method (default)
PKI_EME_OAEP to decode an 'Encoded Message for Encryption' block using OAEP method
PKI_EMSIG_PKCSV1_5 to decode an `Encoded Message for Signature' block using PKCS#1 v1.5 method

If you have selected PKI_EMSIG_PKCSV1_5, then you can add:
PKI_EMSIG_DIGINFO to decode an 'Encoded Message for Signature' block and output the whole DigestInfo data instead of just the message digest.

If you have selected PKI_EME_OAEP, then add one of these options to match the hash function used for EME-OAEP encoding:
PKI_HASH_SHA1 (0) to use SHA-1 (default).
PKI_HASH_SHA224 to use SHA-224
PKI_HASH_SHA256 to use SHA-256
PKI_HASH_SHA384 to use SHA-384
PKI_HASH_SHA512 to use SHA-512
and, optionally, add:-
PKI_MGF_MGF1SHA1 to force the MGF hash function to be SHA-1 (default = same as encoding hash function set above)
The encoding hash function and MGF hash function must match the hash functions used to encode the message.

Alternatively, ignore all the above and use the specialist option
PKI_EMSIG_ISO9796 to use the ISO9796-1 encoding for a signature. See AUTACK messages and ISO/IEC 9796-1 signatures for more details.

Returns (VBA/C)

If successful, the return value is the number of bytes required to store the full output data. If an error occurs, it returns a negative error code.

VBA Wrapper Syntax

Public Function rsaDecodeMsg (lpInput() As Byte, nOptions As Long) As Byte()

.NET Equivalent

Rsa.DecodeMsgForEncryption Method
Rsa.DecodeDigestForSignature Method
Rsa.DecodeMsgIso9796 Method

static Rsa.decode_msg_for_encryption(data, method=EME.PKCSV1_5)

Python Equivalent

static Rsa.decode_digest_for_signature(data, full_digestinfo=False)
static Rsa.decode_msg_for_encryption(data, method=EME.PKCSV1_5)

Remarks

This function recovers the relevant data from an encoded message block according to the algorithms in PKCS#1.

Messages encoded for both encryption and signature using the PKCS#1 v1.5 method are self-contained: that is, they can be decoded with no further information other than the encoded message itself. However, a message encoded using the OAEP method will be assumed by default to have been encoded using the default SHA-1 function for both the encoding hash algorithm and MGF hash algorithm. If you used a different hash function when encoding you need to specify it explicitly in nOptions.

The algorithm RSA-PSS is not available for this function. Use SIG_VerifyData instead.

Decoding an EME Block

The objective is to recover the original message data which is encoded in the block. Use either

nOptions = PKI_EME_PKCSV1_5

or

nOptions = PKI_EME_OAEP

You need to know which algorithm was used to create the block in the first place.

Decoding an EMSA Block

The objective is to verify that the encoded message digest hash matches the message digest hash of the original message.

Note: it is much simpler (and safer) to use the RSA_EncodeMsg() function on the original message and then compare the result of that with the input block you have here. See Raw RSA Techniques. The options here are included for advanced users.

There are two choices when decoding an EMSA block:

  1. Extract the message digest bytes. Set
    nOptions = PKI_EMSIG_PKCSV1_5
  2. Extract the whole DigestInfo bytes. Set
    nOptions = PKI_EMSIG_PKCSV1_5 + PKI_EMSIG_DIGINFO
    You might use this if you come across a hash algorithm that is not supported by this Toolkit. Use this option to recover the entire DigestInfo and then inspect the bytes to work out what it is, using your knowledge of DER encoding.

Remember that the result of a decode operation for a signature is to compare the hash digest encoded in the signature with an independent digest of the original message. If they match, the signature is verified. To avoid an attacker exploiting flaws in the decoding operation, it is safer just to generate another EMSA block from the message and compare that directly.

Example (VBA core function)

    Dim abData() As Byte
    Dim abBlock() As Byte
    Dim abDigest() As Byte
    Dim abDigInfo() As Byte
    Dim nDataLen As Long
    Dim nBlockLen As Long
    Dim nLen As Long
    Dim nRet As Long
    Dim nOptions As Long
    
    ' 0. Create an encoded test block ready for for signing
    abData = StrConv("abc", vbFromUnicode)
    nDataLen = UBound(abData) - LBound(abData) + 1
    nBlockLen = 64
    ReDim abBlock(nBlockLen - 1)
    nRet = RSA_EncodeMsg(abBlock(0), nBlockLen, abData(0), nDataLen, PKI_EMSIG_PKCSV1_5)
    Debug.Print "BLOCK   =" & cnvHexStrFromBytes(abBlock)
    
    ' 1. Extract the message digest =SHA1("abc")
    nLen = RSA_DecodeMsg(0, 0, abBlock(0), nBlockLen, PKI_EMSIG_PKCSV1_5)
    If nLen < 0 Then MsgBox "Decryption Error": Exit Function
    Debug.Print "Message digest is " & nLen & " bytes long"
    ReDim abDigest(nLen - 1)
    nLen = RSA_DecodeMsg(abDigest(0), nLen, abBlock(0), nBlockLen, PKI_EMSIG_PKCSV1_5)
    Debug.Print "HASH    =" & cnvHexStrFromBytes(abDigest)
    
     ' 2. Extract the full DigestInfo data
    nOptions = PKI_EMSIG_PKCSV1_5 + PKI_EMSIG_DIGINFO
    nLen = RSA_DecodeMsg(0, 0, abBlock(0), nBlockLen, nOptions)
    If nLen < 0 Then MsgBox "Decryption Error": Exit Function
    Debug.Print "DigestInfo is " & nLen & " bytes long"
    ReDim abDigest(nLen - 1)
    nLen = RSA_DecodeMsg(abDigest(0), nLen, abBlock(0), nBlockLen, nOptions)
    Debug.Print "DIGINFO=" & cnvHexStrFromBytes(abDigest)

This should produce results like:

BLOCK  =0001FFFFFF...C26C9CD0D89D
Message digest is 20 bytes long
HASH   =A9993E364706816ABA3E25717850C26C9CD0D89D
DigestInfo is 35 bytes long
DIGINFO=3021300906052B0E03021A05000414A9993E364706816ABA3E25717850C26C9CD0D89D

Example (VBA wrapper function)

Dim lpData() As Byte
Dim lpBlock() As Byte
Dim lpDecoded() As Byte
Dim nBlockLen As Long
nBlockLen = 512 \ 8

lpData = cnvBytesFromHexStr("DEADBEEF")

lpBlock = rsaEncodeMsg(nBlockLen, lpData, PKI_EME_PKCSV1_5)
Debug.Print cnvHexStrFromBytes(lpBlock)
lpDecoded = rsaDecodeMsg(lpBlock, PKI_EME_PKCSV1_5)
Debug.Print "DECODED=" & cnvHexStrFromBytes(lpDecoded)

lpBlock = rsaEncodeMsg(nBlockLen, lpData, PKI_EME_OAEP)
Debug.Print cnvHexStrFromBytes(lpBlock)
lpDecoded = rsaDecodeMsg(lpBlock, PKI_EME_OAEP)
Debug.Print "DECODED=" & cnvHexStrFromBytes(lpDecoded)

lpBlock = rsaEncodeMsg(nBlockLen, lpData, PKI_EMSIG_PKCSV1_5 Or PKI_HASH_SHA256)
Debug.Print cnvHexStrFromBytes(lpBlock)
lpDecoded = rsaDecodeMsg(lpBlock, PKI_EMSIG_PKCSV1_5)
Debug.Print "DECODED=" & cnvHexStrFromBytes(lpDecoded)

Debug.Print "DIGEST =" & hashHexFromBytes(lpData, PKI_HASH_SHA256)

See Also

RSA_EncodeMsg RSA_RawPublic RSA_RawPrivate Raw RSA Techniques

[Contents] [Index]

[PREV: RSA_CheckKey...]   [Contents]   [Index]   
   [NEXT: RSA_Decrypt...]

Copyright © 2004-24 D.I. Management Services Pty Ltd. All rights reserved. Generated 2024-01-01T11:51:59Z.