1

I am using a tutorial for RSA implementation from this site: https://sahandsaba.com/cryptography-rsa-part-1.html

They use this function for encryption:

def power(x, m, n):
    """Calculate x^m modulo n using O(log(m)) operations."""
    a = 1
    while m > 0:
        if m % 2 == 1:
            a = (a * x) % n
        x = (x * x) % n
        m //= 2
    return a

def rsa_encrypt(message, n, e):
    return modular.power(message, e, n)

and then he encrypts a number:

>>> message = 123
>>> cipher = rsa_encrypt(message, n, e)

How do I encrypt entire String though? I want to encrypt string generated by a hash using this implementation.

1
  • 1
    strings are characters, characters have an ascii value ord('B') - value which is an integer. build a chain that conversts string -> ord -> rsa and rsa -> ord -> string - Hashes are normally not reversable, so you will only be able to restore the hash - not the original string. Commented May 5, 2018 at 8:22

1 Answer 1

2

The two functions you are missing are those for going from a sequence of bytes to a number, and back:

def bytes2num(b):
    return b[0] + 256 * bytes2num(b[1:]) if b else 0

def num2bytes(n):
    return bytes([n % 256]) + num2bytes(n // 256) if n else b''

If you want to work with strings you can define the functions:

def str2num(s):
    return bytes2num(s.encode('utf-8'))

def num2str(n):
    return num2bytes(n).decode('utf-8')

You should make those implementations iterative if your messages are very long.

Test:

>>> s = 'Hello, world!'

>>> str2num(s)
2645608968347327576478451524936

>>> num2str(2645608968347327576478451524936)
'Hello, world!'
Sign up to request clarification or add additional context in comments.

13 Comments

No, you don't need to split the string in blocks. See also this question: crypto.stackexchange.com/questions/32344/…
@sushionthefork: It creates a big number from the bytes values. If the byte sequence s is composed of <b0, b1, b2, ..., bN>, then the number representing it is b0*256^0+b1*256^1+b2*256^2+...+bN*256^N
@sushionthefork: as a further clarification, you can see the byte sequence just as a base256 number, so that's the usual conversion to/from base10.
It's an inline if. Another way to write that would be if b: return b[0] + 256 * bytes2num(b[1:]); else: return 0. Returning 0 when the byte sequence is empty is the base case of that recursive function.
@fferri In python 3 (which I assume you're using, due to the str/bytes naming), you can replace the custom logic of bytes2num/num2bytes with builtins: int.from_bytes(b, 'little') and n.to_bytes((n.bit_length() - 1) // 8 + 1, 'little'), respectively.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.