问题
我试图在python和java/android之间配置非对称加密。该用例安全地存储用户密码(使用公钥),允许对服务器(具有私钥)进行重新身份验证。在
我已经在Python和Java中分别使用了加密算法,但无法让Python方面解密Java生成的密文。我认为两个最有可能的问题是base64编码字符串的问题(一直在与这些问题作斗争!),或
客户端/服务器之间的填充和其他加密规范不匹配
为了在这里创建一个完整的示例,我将复制私钥和公钥,然后重新生成一个新的集以供实际使用。在
Java(客户端)端代码:
Java导入// Java imports
import android.util.Base64;
import android.util.Log;
import java.security.KeyFactory;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.spec.MGF1ParameterSpec;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import javax.crypto.Cipher;
import javax.crypto.spec.OAEPParameterSpec;
import javax.crypto.spec.PSource;
Java加密代码-对于代码格式/宽度,我深表歉意。。。在
^{pr2}$
如果我使用输入字符串=“test text”运行这些代码,则会得到加密的输出:BoOymgUGnB/LIqYOhBmW60HCL4s6FQFlNpRmhqm63AGq7gud4g96og6f+5yHUVHktAT0pl93UpAz//aae4esTseR6/o7jD/NGS+gZlNRHsSuNNstVZ8wOp1S03YcHYEpXtTdElMiKso4cbZmO20SoUvyzjI5e7RM1aWKCebqCvG7RYneCgoMi611AY2cVSwMYOENcRwqXeB3sFMrjoNQ1TkkgHU5MSxDbVLbNO72AYYQi/TkwiQ57qnjgk3KHXeatJv/5hWqa5ooBCy6aLDFux6X2721wTVa2/RSiZKG7DJHObV5pQNw4zjGWc4d5IJ+P/o6GKHY4fTj8ujqS6A44Q==
我确信这是可行的,因为我可以用私钥成功地解密它(使用另一个代码块,这里不复制)。在
然后将其用作python代码的输入。在
Python(服务器端)代码
Python导入from cryptography.hazmat.primitives import serialization, hashes
from cryptography.hazmat.primitives.asymmetric import rsa, padding
from cryptography.hazmat.backends import default_backendb
Python解密代码PRIVATE_KEY_STRING='-----BEGIN PRIVATE KEY-----\nMIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDqRMUmX7qMbat9\niVnG0WLNqM6C8qAickc5riLcbm8H1zt/uTOxMw6Z6Dlgefcs2d2DhbHgDJ83l9tw\n0aD4qYkr3VvaWSAXLulUSFZ/Mrj/KqTSWIbszC43QbwapSMiok5c9LqVcH1mvef1\nDJOQoZX1yc1U9XUI243ds67S3wy7d+9n7Px52r9x9SlNfAN19GZnpZ5bHGqiAra4\nLCad4Q3ySrJYTg7GHKoskzD2YIYc6pNWAlSe+MwF7PLCvqze8hyzZDsKfFDH+D8Z\nOqFTEtIcOXIAUNuFTgFaQIesJr+dPIgWBcL1fhhGlB3bjF8ZcmMHapRW/YfQ7kWh\nEkARi9J9AgMBAAECggEARuUi6JcFxGOYBzies51AEk7omBZGwcXlqh35rM26yhun\nhOKOMyzpWUg+vOSMGcWg1KGMD+qh8FgDb6Pw2++qdFzb5DsejAWFVR1DF+FIvOex\n03o48sZjohNBkqqw9FU788OYB4twV7xWywDQU2+jCyvT+McDcPfIefRbjrMzjjOM\nOhMY0F6OXeDpuZttgqZsP65aA7yaIfjuk5tuYbpZvNmV1DAlqfGmxt2PO1laobGQ\nS7Vx18zpWWdh/GgnbZDD3SG69AmAWIdOZNV6SuUC5lgOqw2O+8TB7MXFbiCy7v5J\n1tMap6OCRDm5jLsc6ZFP5Zs1s9/FnW9/jCxw4kFxPQKBgQD7DcVUaW7rKUmYORAA\nqY6uAIu+Lo+607G4Nva52Rotj0vdiIsAYxJPP2dxKTjL0GLbKIsOcmd2xD0e1/yu\nlAu6koCyC5cT5XwNJ388XDwtWPU2J7mC1TKq0TJUZ56uzdZxNKOWQ7Upq3901zbQ\nQhssjJpgX09CPzlfpAc9NHhchwKBgQDu4lc5HaJNsFeEMOuaUmTUu+W+veIZZaV3\n7yTnLxoJCyqu5DVKvhMwDZP3I2JuvHbCPf3AzshvNcbCiG/6u9CQSbv4wRZO6p8c\nlIAymy0neaq7+uxHdvem58A4xIlKhlnNpzIqE9fay7ejAklGPTFs/YdsyVXwADVr\n30cfOdO92wKBgCCrGhJx5c0UAk+cnUh4x+g8ifKlfG6DPY0LGe/1IELtcqHRMsVK\nHwfQ6FUBWDKtWy/Jhs7KdEwwHQP2dxsAiMYuajDA8VfVdN8BVL02A16jRMVXRfyQ\nYZd4wWPaV/vHLTBt+RuEk/5oIp3Bo5BWCdMyOKRxwo6MS5r2bTq5qS/hAoGAKezT\nfhSzXYsrcOndD7KSO7vWcImG2wo55ji0c1aS7S9miFdI+xss5uwbIe614dV1ylVy\n6ZnhF5OKlK25aXn4+rnWIaxRq/wFfNCbR0ZwwFLcIi3BtjEs+cAGvm/P4KJ/tFY5\nuaTN53qFejh2f7tRp10/nVogmQSQW6ROKS7O+K0CgYA03s/ajxaYTLzBHpIdqisl\nsGaen4IBibB3OZs/vplBZ0xG34B8+MC8qgvC6DFVR4Y3XMol8lOGiS6OQVvIRjnC\nhqd/QobpH0j5Wy2cM+6yXVvj95dwif7QjaqDydniRhGbxa6iJ8vTYqyl9yNjWwX/\n72JRzDNB+9De2LntVwzBwA==\n-----END PRIVATE KEY-----\n'
#Load the java output into a bytes object to decrypt
java_out = b'BoOymgUGnB/LIqYOhBmW60HCL4s6FQFlNpRmhqm63AGq7gud4g96og6f+5yHUVHktAT0pl93UpAz//aae4esTseR6/o7jD/NGS+gZlNRHsSuNNstVZ8wOp1S03YcHYEpXtTdElMiKso4cbZmO20SoUvyzjI5e7RM1aWKCebqCvG7RYneCgoMi611AY2cVSwMYOENcRwqXeB3sFMrjoNQ1TkkgHU5MSxDbVLbNO72AYYQi/TkwiQ57qnjgk3KHXeatJv/5hWqa5ooBCy6aLDFux6X2721wTVa2/RSiZKG7DJHObV5pQNw4zjGWc4d5IJ+P/o6GKHY4fTj8ujqS6A44Q=='
#Load the private key string into a functioning key object
private_key = serialization.load_pem_private_key(
PRIVATE_KEY_STRING.encode('UTF-8'),
password=None,
backend=default_backend()
)
#Decrypt the input
private_key.decrypt(
java_out,
padding.OAEP(
mgf=padding.MGF1(algorithm=hashes.SHA256()),
algorithm=hashes.SHA256(),
label=None
)
)
使用相同的代码(和另一个要加密的块),我可以在Python中成功地加密/解密。但是,当使用Java的输出作为输入时,此代码返回以下错误:---------------------------------------------------------------------------
ValueError Traceback (most recent call last)
in ()
4 mgf=padding.MGF1(algorithm=hashes.SHA256()),
5 algorithm=hashes.SHA256(),
----> 6 label=None
7 )
8 )
C:\ProgramData\OWTools\miniconda\lib\site-packages\cryptography\hazmat\backends\openssl\rsa.py in decrypt(self, ciphertext, padding)
384 key_size_bytes = int(math.ceil(self.key_size / 8.0))
385 if key_size_bytes != len(ciphertext):
--> 386 raise ValueError("Ciphertext length must be equal to key size.")
387
388 return _enc_dec_rsa(self._backend, self, ciphertext, padding)
ValueError: Ciphertext length must be equal to key size.
一个可能有用的想法是,在要加密的python代码中,密码文本的格式如下:b'N\xf2\xa7\xfaW6[Z\x0c\x14\xe7\xc8\xcb\xed\xa2xM\xea\x83\xa3\xb7\x05few!\x0e\\zd\xfe g\xbbO1\xfe\n\xa0Q\xab\xb8e0\xe9R^\xc8\xbbU\xfbuxp\x00\xf7>\xf8\x14\x1c\xd7\xca}\xd3\n{\xc9\xa2^\x8c0.\x9a\\\xe2\x89\xfd\xbf\xabw\x03\xc4\xdc\xfdX\xcf\xcc\x01\xc7\xc8\\j\xa9\xd7U\xfbP\xc2$\xd9^\x9e1\x9d&\xf1\x1b\x08%\xb3kF`\x19\xeb\xc8\xf0\x9f\xb1\x13\xaa\xa1\xed+X\xdc\x10!Fw\xae\x93\xb0\x80\xf3}\x98nz^\x04\xfe\x08T\x98d>[\xa7\x92\x08\x8a\r\xbc\x85\xf8\xcb\xce\xcc\x94\x95V\xf0\xad\x8d\x94N\x0c\x03\xf0\xbcT\x06%\x0b\x06\xcb_\xcauY$\n\xbc\xea\xde\xe4G\x05F\xf5\xef\x10\x83w"f5*&?\\9\x08\xd3}\xf0X\xb7\x06F\x99\xe1\xf3\x02\x14a\x7f\x1a0,?{\x12^|\xba\xed\xf6s\xed\xe6@m\xc7ex\x86\xf1\xae\xeec=\x92\x7fZ\x19\xee\x0f\x86\xb8\xf5T_\x9f\x1c'
这显然与java的输出完全不同——尽管我不完全确定为什么(或者这意味着什么!)在
非常感谢任何帮助!谢谢