Decodes an EME or EMSA encoded message block according to PKCS#1 (EME = Encoding Method for Encryption, EMSA = Encoding Method for Signature with Appendix).
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)
long __stdcall RSA_DecodeMsg(unsigned char *lpOutput, long nOutBytes, const unsigned char *lpInput, long nInputLen, long nOptions);
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.
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.
Public Function rsaDecodeMsg
(lpInput() As Byte, nOptions As Long) As Byte()
Rsa.DecodeMsgForEncryption Method
Rsa.DecodeDigestForSignature Method
Rsa.DecodeMsgIso9796 Method
static Rsa.decode_msg_for_encryption(data, method=EME.PKCSV1_5)
static Rsa.decode_digest_for_signature(data, full_digestinfo=False)
static Rsa.decode_msg_for_encryption(data, method=EME.PKCSV1_5)
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.
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.
The objective is to verify that the encoded message digest hash matches the message digest hash of the original message.
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:
nOptions = PKI_EMSIG_PKCSV1_5
DigestInfo
bytes.
Set
nOptions = PKI_EMSIG_PKCSV1_5 + PKI_EMSIG_DIGINFOYou 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.
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
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)
RSA_EncodeMsg RSA_RawPublic RSA_RawPrivate Raw RSA Techniques