ISO/IEC 9796-1 formatting takes a message of limited length and "weaves" it into a padded block the same size in bytes as the RSA key modulus.
It allows message recovery, but is more secure if used to format a message digest of the original message.
It requires knowledge of the exact size of the key modulus in bits.
The encoded message will always be one bit shorter than the key length, as far as significant bits are concerned.
However, the returned byte array will always be the same size as the key in bytes; i.e., ceil(keybits/8)
bytes.
For an extreme case like a 1025-bit key, it will return a byte array of 129 bytes with the most significant byte zero.
We use the RSA_EncodeMsg
function and pass an option parameter
consisting of the PKI_EMSIG_ISO9796
flag plus the actual size of the key in bits. Do not use any other flags.
To decode and recover the message, use the RSA_DecodeMsg
function
in the same manner. In VB6/VBA:
' Encapsulate hash digest in ISO9796-1 encoding ' -- we need a block of the same length as the key in bytes nKeyBits = RSA_KeyBits(strPrivateKey) Debug.Print "RSA key length=" & nKeyBits & " bits" blen = RSA_KeyBytes(strPrivateKey) ReDim abBlock(blen - 1) ' plus pass the exact key length in bits as part of the option parameter... r = RSA_EncodeMsg(abBlock(0), blen, abDigest(0), dlen, PKI_EMSIG_ISO9796 + nKeyBits) Debug.Print "RSA_EncodeMsg returns " & r & " (expecting >=0)" If (r < 0) Then Exit Function Debug.Print "Encoded block ready to sign=" & vbCrLf & cnvHexStrFromBytes(abBlock)
In C# and VB.NET/VB20xx, use the special Rsa.EncodeMsgIso9796
and Rsa.DecodeMsgIso9796
methods.
keyStr = Rsa.FromXMLString(xmlKey, false);
keyBits = Rsa.KeyBits(keyStr);
Console.WriteLine("Private key is {0} bits long", keyBits);
// Compute message digest of data
hexDigest = Hash.HexFromString(msgStr, HashAlgorithm.Sha1);
Console.WriteLine("Message-to-encode=Digest={0}", hexDigest);
// Convert digest to byte array
msg = Cnv.FromHex(hexDigest);
// Encode digest using ISO-9796-1
b = Rsa.EncodeMsgIso9796(msg, keyBits);
Debug.Assert(b.Length > 0, "Failed to Encode for ISO9796-1");