Crypto.RSA with key sizes < 512 bits?

I have some legacy code which uses RSA with 128 bit key using a 3rd party plugin. I tried to update my code to use the new Crypto module but it chokes on doing anything useful with key sizes below 512. I know using small key sizes is not a good default, but there are cases where it makes sense. Can Xojo’s Crypto module support this?

What do you mean by “chokes”? Exception? Crash? Bad data?

Various CrytpoExceptions are thrown at runtime, depending on what I’m trying to do, but most of them say something like "Key size is too small for _______ " . If I increase the key size to 512 or greater then I don’t get the exception.

Encrypt smaller amounts of data.

Doesn’t work:

   dim pri,pub as string
   If Crypto.RSAGenerateKeyPair( 128, pri,pub ) Then
      // Testing smaller key sizes
      Dim msg As String = "0123456789ABCDEF" // 16 bytes
      Dim signature As MemoryBlock = Crypto.RSASign( msg, pri )
      If signature <> Nil Then
        // msg was successfully signed
      End If
    End If

Exception gives " Key too short for this signature scheme"

Submitted as <https://xojo.com/issue/39945>

It’s not a bug. The maximum length in using a 128-bit key is -26 bytes. It’s impossible. The formula is (KeySize / 8) - 42. 42 is the header size. So my “encrypt smaller amounts of data” wasn’t good advice, I’m sorry. You need a larger key.

It depends on the details of what package & options are chosen. I have another package which will do the bare RSA (128 bit key = 16 byte plaintext). Here’s another source which claims that the formulas is (Keysize/8) - 11. (not 42 as you say) http://golang.org/pkg/crypto/rsa/#EncryptPKCS1v15

Need more info about what’s going on inside the Crypto module. The Language Reference refers to http://cryptopp.com but I’m not finding the padding info there.

The header is definitely 42.

It’s a RSASSA_PKCS1v15_SHA_Signer that you can look up. You shouldn’t use padding with PKCS1.5 to make up for length, that’s been broken for years- and not something we’d enable in the framework.

Where does 42 come from? Another source says “11” for version 1.5 padding:
https://tools.ietf.org/html/rfc2313

I wish I had the reference somewhere. I think it was Greg who told me it was 42, but I can’t say for sure who. All I know is all my tests confirm 42.

Ok, let me change the discussion slightly: I’m actually not interested in the Crypto.RSASign, but rather Crypto.RSAEncrypt, in case that affects the padding discussion.

It sounds like there are 3 possible padding schemes for RSA:

  • None, also called “Naked RSA” or “Textbook RSA” - not recommended, however I believe this is what my legacy code used and was able to encrypt/decrypt 16 bytes using a 128 bit key. I’d like to be able to support that if possible.
  • PKCS 1.5 : not recommended, but sounds like it results in a plaintext size of (KeyLength/8-11)
  • RSAS-OAEP padding (described in section 7.1.1 here: http://www.ietf.org/rfc/rfc2437.txt ) which gives a maximum key length of

[quote] message to be encrypted, an octet string of length at most k-2-2hLen, where k is the length in octets of the modulus n and hLen is the length in octets of the hash function output for EME-OAEP
[/quote]

Does the library actually use OAEP padding?

Digging into the source code (Yay open source!) I find the maximum plaintext length number calculated in a few places:

For OAEP padding:

size_t OAEP_Base::MaxUnpaddedLength(size_t paddedLength) const
{
	return SaturatingSubtract(paddedLength/8, 1+2*DigestSize());
}

For PCKS padding:

size_t PKCS_EncryptionPaddingScheme::MaxUnpaddedLength(size_t paddedLength) const
{
	return SaturatingSubtract(paddedLength/8, 10U);
}

Yes. Xojo is not going to be backwards compatible to the insecure shorter keys you mention.

For <https://xojo.com/issue/39945> - can we convert that from a bug report to a documentation request to make these issues known in the LR? Or shall I submit a new Feedback case?

I did some experiments a while back. See https://forum.xojo.com/20098-crypto-rsaencrypt