Cryptography: Raw RSA encryption and decryption (without padding)

Created on 25 May 2017  路  11Comments  路  Source: pyca/cryptography

Is possible to realize this insecure operation? Obviously, having a bytesobject of the key length.

api design primitives

All 11 comments

This is currently not supported, and we're unlikely to add support -- I'm not aware of any major protocols that require this, so the footgun-to-utility ratio isn't very good. What is your usecase?

I'm migrating an old Python code that uses PyCrypto to implement a highly unsafe legacy and rare-as-a-green-dog protocol. Implementing it only for me is a madness.

Understanding all the hazards that it carries 馃槇 would you accept a PR implementing this?

Also, it would be great to have this ability for the developers (maybe a dozen in the world) that need to implement a custom data schema.

Chef needs this as well (mentioned in https://github.com/pyca/cryptography/issues/1648 somewhere in the comments).

Since we already have support for Prehashed it would now be possible to do a Textbook that you pass to get raw RSA operations.

While it's possible, I maintain my position that the frequency with which this is requested is extremely low, relative to just how big of a footgun it is.

Folks who need this for migration purposes can use pow(bytes2int(digest), key.public_numbers().e, key.public_numbers().n). Two requests in 4+ years is not enough given just how bad of an API this would be.

I exactly need to do this (as suggested by @reaperhulk here):

signature = key.sign(data, padding.PKCSv15(), None)

The "signed" (reversely-encrypted data) would look like this:

00 01 FF FF FF FF FF FF FF FF 00 DA 7A DA 7A DA 7A DA 7A DA 7A DA 7A DA 7A

Maybe I posted an X-Y issue. My implementation uses PKCS#1 1.5 for signing (signing the data, not a hash)

Would you find useful to implement the above thing? Also I would need to verify (do the inverse process).


@alex: Is not as elegant as I would desire, but is the best solution I can find for now. Thanks!

If anybody finds it useful, here is the code I'm using now based on @alex suggestion (sorry Mr. PEP8, this is only for testing):

def sign(plaintext, private_key):
    d = private_key.private_numbers().d
    n = private_key.public_key().public_numbers().n
    plaintext = bytes([0x00, 0x01]) + bytes([0xff] * int(private_key.key_size/8 - len(plaintext) - 3)) + bytes([0x00]) + bytes(plaintext)
    return pow(int.from_bytes(plaintext,'big'),d,n).to_bytes(int(private_key.key_size/8), byteorder='big')

def verify(ciphertext, public_key):
    e = public_key.public_numbers().e
    n = public_key.public_numbers().n
    plaintext = pow(int.from_bytes(ciphertext,'big'),e,n).to_bytes(int(private_key.key_size/8), byteorder='big')
    assert plaintext[:2] == bytes([0x00, 0x01])
    return plaintext[plaintext.find(bytes([0x00]),2)+1:]

PKCS#1v15 is different from raw RSA encryption. You should be able to accomplish it using the Prehashed helper @reaperhulk mentioned.

@alex: I've tried already the Prehashedhelper without luck. To end horrifying you, I need to stuff 112 bits of data into a 200 bit message. The rest is PKCS#1 1.5 0xFF padding, as I stated on my last post.

I'll probably try to familiarize with your code and do a PR implementing what I need (if you assure me that will be accepted, of course).

I think that implementing raw RSA, as stated in my first post, will allow more flexibility. Also, if the primitives are hazardous, let's go mad and expose textbook RSA! 馃槇 Seriously, this would allow custom implementations of rare padding algorithms and any uncommon protocol using your library.

If you prefer accept the implementation of the Prehashed helper with custom algorithms for signing and verification, it will be fine for my case, but that dozen of human beings around the world which need access to the low-level RSA functions will be sad. 馃槧

If you choose not to implement it, please let me know so I can refine the odd job posted above and close the issue. Else, let's discuss the implementation details.

I remained opposed to adding this, the increased flexibility comes at the expense of increased confusion and potential for mistakes in the API. Hazmat is not an excuse for failure to balance these concerns against the utility of new functionality. Unless @reaperhulk feels strongly I will close this.

I think that is a good idea to allow the developer to craft custom recipes backed by an strong and flexible API. The flexibility and the confusion aren't directly proportional always.

Closing for now. If you disagree @reaperhulk feel free to reopen.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

danetrain picture danetrain  路  43Comments

tiran picture tiran  路  30Comments

ctismer picture ctismer  路  29Comments

reaperhulk picture reaperhulk  路  22Comments

alex picture alex  路  28Comments