RSA algorithm padding method

During the development process, it was found that after the ciphertext encrypted by RSA on the iOS side was sent to the server side, the server side could not parse it. Originally, I wanted to compare the encryption results of the same plaintext to judge the difference between the encryption methods of the server side and the iOS side, and found that Encryption results have always been different. Then the server tries to encrypt the same piece of plaintext multiple times, and the result is different. 


Then was shocked. I also know the principle of RSA who have studied cryptography, similar to:
  1), ciphertext = plaintext ^e mod n
  2), plaintext = ciphertext ^d mod n
  3), then publickKey = (e,n), privateKey = (d,n)


After research, it is found that the current RSA algorithm actually adds a random value in the encryption process, so the result of each encryption will be different. So since the result of each encryption is different, how to decrypt, the specific scheme is as follows:
 1), ciphertext = (random+plaintext) ^e mod n //publicKey encryption
 2), (random+plaintext) = ciphertext^d mod n //The server uses privateKey to decrypt
 3), plaintext = (random+plaintext) - random //After the server decodes random


 and solves this question, it returns to the first question, why the result of iOS encryption cannot be solved Woolen cloth. The answer is that there are many ways to add random numbers to the RSA algorithm, because the padding method set by iOS is different from the padding method of the server (that is, the method of adding random numbers), so that the server cannot parse the ciphertext.


 There are three commonly used padding methods for RSA encryption:

1. RSA_PKCS1_PADDING padding mode, the most commonly used mode
Requirements :
Input: must be at least 11 bytes shorter than the RSA key modulus (modulus), which is RSA_size(rsa) – 11
If the input plaintext is too long, it must be cut and then padded
Output : as long as the modulus
According to this requirement, for 512bit key , block length =

512/8
11 = 53 bytes The input plaintext is too long and must be cut and then filled




output: as long as modulus


The RSA code that implements RSA_PKCS1_PADDING padding in python is as follows:


import cgi, base64
from Crypto.PublicKey import RSA
from Crypto.Cipher import PKCS1_v1_5
from Crypto.Hash import SHA
from Crypto import Random

# private key file
priKey = '''-----BEGIN RSA PRIVATE KEY-----
xxxx
-----END RSA PRIVATE KEY-----'''

# public key file
pubKey = '''-----BEGIN PUBLIC KEY-----
xxxx
-----END PUBLIC KEY-----'''

# pseudo random number generator
random_generator = Random.new().read


'''*RSA encryption
* data data to be encrypted
* The final encrypted result needs to be encoded with base64
* return encrypted result
'''


def rsa_encrypt(data):
    key = RSA.importKey(pubKey)
    cipher = PKCS1_v1_5.new(key)
    cipher_text = base64.b64encode(cipher.encrypt(data))
    return cipher_text


'''*RSA decryption
* encrypt_text data to be decrypted
* Private key for decryption
* return decrypted result
'''


def rsa_decode(encrypt_text):
    key = RSA.importKey(priKey)
    cipher = PKCS1_v1_5.new(key)
    text = cipher.decrypt(base64.b64decode(encrypt_text), random_generator)
    return text

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325721232&siteId=291194637