Score:3

Is there an easy way to make textbook RSA secure enough so it can be used in real life?

cn flag

I have written a raw (textbook) RSA implementation (just for fun) and I wonder is there an easy way to make it secure enough so it can be used in real life (without implementing OAEP+ and RSASSA-PSS)? Are there any simple algorithms for padding and generating secure digital signatures?

kelalaka avatar
in flag
And [PKCS1-v1_5 Signature Scheme](https://crypto.stackexchange.com/a/88101/18298) has a proof _from a provable security perspective RSA PKCS#1 v1.5 can be safely used, if the output length of the hash function is chosen appropriately_
Brongs Gaming avatar
cn flag
Thanks for the answer, @kelalaka!
Score:7
my flag

Actually, RSASSA-PKCS1-v1_5 signature padding is quite simple, and has no known weaknesses (the similarly named RSAES-PKCS1-v1_5 padding is broken for encryption unless implemented in a very very careful way; don't use that).

The padding format is:

00 01 FF FF FF ... FF FF 00 <DER of Hash Type> <Hash>

where DER of Hash Type is a byte string that depends on the type of hash you used, and Hash is the output of the hash function. For SHA-256, the DER is the byte string:

30 31 30 0d 06 09 60 86 48 01 65 03 04 02 01 05 00 04 20

So, you take your hash, prepend it with a fixed string, and you're done.

If you want to make things a bit simpler, you could omit the DER of Hash Type (which would mean that you're not precisely PKCS #1.5, however it does not introduce any known weaknesses.

Brongs Gaming avatar
cn flag
Thanks for the answer! Did I understand correctly that RSASSA-PKCS1-v1_5 can be used only for generating digital signatures?
SAI Peregrinus avatar
si flag
Yes, that's only for signatures. RSA encryption is mostly useful as a building-block for other constructs (eg homomorphic encryption). The simple alternative would be RSA-KEM, which isn't exactly encryption (it exchanges a random number which is used to derive an encryption key for use with a symmetric AEAD) but is simple and secure.
poncho avatar
my flag
@BrongsGaming: well, yes, however the question did ask 'Are there any simple algorithms for padding and generating secure digital signatures?' - you didn't ask for simple algorithms for encryption. For that, the simplest might be "don't do padding at all; instead, have the encryptor pick a random value between 2 and $n-2$, and textbook RSA encrypt that; use the original random number you picked to generate a symmetric key and use that symmetric key to encrypt the message you want to send.
SAI Peregrinus avatar
si flag
Of note, RSA-KEM is essentially a more-formal version of that (it specifies how to use the random number to generate a symmetric key and a few other bits about the format).
Brongs Gaming avatar
cn flag
Thanks @SAI Peregrinus and @poncho! Sorry for my question not being clear. I am a newbie to this stuff and English is not my native language. :)
Brongs Gaming avatar
cn flag
@poncho, but how can I securely transfer that random number if textbook RSA is considered insecure?
poncho avatar
my flag
@BrongsGaming: the reason textbook RSA is considered insecure is a) because it's determenistic; the attacker can guess plaintexts and encrypt them - if they guess correctly, he knows the plaintext, and b) RSA's homomorphic properties; if the value being encrypted is a smooth number, that is, a product of small primes, then the attacker can recover that plaintext surprisingly quickly. Neither of these apply to RSA-KEM (where you pick a random n-bit number)
poncho avatar
my flag
@Gilles: actually, RSASSA-PKCS1-v1_5 is a signature padding format (and can't be used for encryption, as it's deterministic). You're thinking about RSAES-PKCS1-v1_5; that is weak, however I describe the RSASSA padding format in enough detail that there really shouldn't be any confusion
Gilles 'SO- stop being evil' avatar
cn flag
Ah, sorry, I oversimplified the sentence too much. I do think it's important to insist that it's only PKCS1v1.5 signature that's ok, and not PKCS1v1.5 encryption.
Score:6
in flag

There is also a more simple but not well-known signature scheme for RSA;

It has existentially unforgeable under adaptive chosen-message attacks in the random oracle model.

Today RSA-FDH is very simple;

  • Sign: $\sigma = Sign(H, m) = (H(m))^d \bmod n$
  • Verify: $\{0,1\} = Verify(H, m, \sigma) = [\sigma^e \bmod n \overset{?}= H(m) \bmod n]$

It was not easy to sign then because of the size requirement; the hash $H$ must have an output size equal to RSA modulus size. Now, the obvious choice is the eXtendible Output Functions (XOF) like SHAKE128/SHAKE256 of SHA-3.

Request output size from SHAKE128(or SHAKE256) equal to RSA modulus size, hash it then sign, that's it!


import hashlib
import rsa

(pubkey, privkey) = rsa.newkeys(2048)


FHD = hashlib.shake_128()
FHD.update(b'Message to Sign')
digestFDH = int.from_bytes(FHD.digest(255),byteorder='little')

#just m^d mod n    
signed = rsa.core.decrypt_int(digestFDH,privkey.d,pubkey.n)

#just m^e mod n
if digestFDH == rsa.core.encrypt_int( signed ,pubkey.e,pubkey.n):
    print("Verified")
else:
    print("!!!Verification failed. Halt!!!")

The exact definition as in 1998 paper (not in quotes)

The signing and verifying algorithm have oracle access to a hash function $H_{FDH} : \{0, 1\}^∗ \to \mathbb{Z}^*_N$. Signature generation and verification are as follows :

$\operatorname{SignFDH}_{N,d}(M) $
$\quad y \leftarrow H_{FDH}(M)$
$\quad \text{return }y^d \bmod N$

$\operatorname{VerifyFDH}_{N,e}(M, x)$
$\quad y \leftarrow x^e \bmod N;$ $\quad y' \leftarrow H_{FDH}(M)$
$\quad\text{if }y = y' \text{ then return }1 \text{ else return } 0$

and note that, at least some of the elements of the $\mathbb{Z}_N^*$ cannot be output by a standard XOFs. The modulus is not an exact power of 2, so one needs to output one bit less than the modulus. The library that I've used for the sample implementation uses bytes for output size, so it cannot cover up to 8-bit.

Also, the all-zero output is excluded!.

Brongs Gaming avatar
cn flag
Thanks for the answer! Interesting idea. But where did you request output size from Shake128 to be equal to RSA modulus size in this code snippet?
kelalaka avatar
in flag
`digest(255)`, and note that I don't claim this is secure implementation especially against side-channels, [little info](https://crypto.stackexchange.com/q/75408/18298). You may need to use a secure one. See [the warning of the library](https://pypi.org/project/rsa/)
Maarten Bodewes avatar
in flag
Comments are not for extended discussion; this conversation about the fact that above is an **almost FDH** signature has been [moved to chat](https://chat.stackexchange.com/rooms/131177/discussion-on-answer-by-kelalaka-is-there-an-easy-way-to-make-textbook-rsa-secur).
Ruggero avatar
kr flag
Aren't the best bounds the ones from "Optimal Security Proofs for Full Domain Hash, Revisited" by Kakvi and Kiltz ?
kelalaka avatar
in flag
@Ruggero It seems I've missed that. Thanks, I'll update after read more...
Score:2
vu flag

Other answers had given a good overview of RSA signature schemes that has simple paddings that can be used securely.

I'd like to bring the attention of readers to the "RSA-KEM" encryption scheme (since this question is also tagged OAEP) specified in a standard-track RFC (which specifies its use in CMS the Cryptographic Message Syntax environments).

https://datatracker.ietf.org/doc/html/rfc5990#appendix-A

In essence, it's like a encryption counter part to the "full domain hash", where the key material encrypted by the RSA algorithm is "full-domain", that is, it's a value chosen, uniformly random, within the range of $[0,N)$ where $N$ is the public modulus.

It then use a key derivation function to derive a key, which is then used in a key-wrapping encryption.

Brongs Gaming avatar
cn flag
Thanks for the answer!
mangohost

Post an answer

Most people don’t grasp that asking a lot of questions unlocks learning and improves interpersonal bonding. In Alison’s studies, for example, though people could accurately recall how many questions had been asked in their conversations, they didn’t intuit the link between questions and liking. Across four studies, in which participants were engaged in conversations themselves or read transcripts of others’ conversations, people tended not to realize that question asking would influence—or had influenced—the level of amity between the conversationalists.