我想在我的服务器(Python FastAPI)和 Android 应用中添加 RSA 加密。
但是加密效果不如我预期。
我的 Python 和 Kotlin 代码之间已经实现了 AES-GCM 加密/解密。但是,Python 和 Kotlin 中的 RSA 加密尝试无法互相操作。
Python(服务器)RSA 代码可以解密 Python RSA 代码加密的内容,而 Kotlin(应用程序)RSA 代码可以解密 Kotlin RSA 代码加密的内容。
我使用了 Python 中的加密模块和 Kotlin 中的原生加密。
这是我的 Python 文件。
import os, base64, re
from cryptography.hazmat.primitives.asymmetric import rsa, padding
from cryptography.hazmat.primitives import serialization, hashes
from cryptography.hazmat.backends import default_backend
if os.path.exists("private.key") and os.path.exists("public.key"):
print("Loading existing keys")
with open("private.key", "rb") as pkf, open("public.key", "rb") as kf:
pk = serialization.load_der_private_key(pkf.read(), None, default_backend())
k = serialization.load_der_public_key(kf.read(), default_backend())
else:
print("Generating new keys")
pk = rsa.generate_private_key(65537, 4096, default_backend())
pkb = pk.private_bytes(
serialization.Encoding.DER,
serialization.PrivateFormat.PKCS8,
serialization.NoEncryption()
)
k = pk.public_key()
kb = k.public_bytes(
serialization.Encoding.DER,
serialization.PublicFormat.SubjectPublicKeyInfo
)
with open("private.key", "wb") as pkf, open("public.key", "wb") as f:
pkf.write(pkb)
f.write(kb)
def enc(text):
return base64.b64encode(k.encrypt(
text.encode(),
padding.OAEP(
mgf=padding.MGF1(hashes.SHA512()),
algorithm=hashes.SHA512(),
label=None
)
)).decode()
def dec(ciphertext):
return pk.decrypt(
base64.b64decode(ciphertext),
padding.OAEP(
mgf=padding.MGF1(hashes.SHA512()),
algorithm=hashes.SHA512(),
label=None
)
).decode()
while (inp:= input("RSA: ")) != "":
if re.match(f"^enc", inp):
print("Encrypt", enc(inp[3:].strip()))
if re.match(f"dec", inp):
print("Decrypt", dec(inp[3:].strip()))
这是我的 Kotlin 文件。
import java.security.KeyPair
import java.security.KeyPairGenerator
import java.security.SecureRandom
import java.security.KeyFactory
import java.security.PublicKey
import java.security.spec.X509EncodedKeySpec
import java.security.spec.PKCS8EncodedKeySpec
import javax.crypto.Cipher
import javax.crypto.SecretKey
import javax.crypto.KeyGenerator
import javax.crypto.spec.SecretKeySpec
import javax.crypto.spec.GCMParameterSpec
import java.util.Base64
import java.io.File
import java.nio.file.Files
fun main(){
print("Text: ")
val encrypted = rsaEncrypt(File("public.key"), readLine().toString())
println(encrypted)
print("Ciphertext: ")
println("Decrypted: ${rsaDecrypt(File("private.key"), readLine().toString())}")
}
fun bEncode(data: ByteArray) = Base64.getEncoder().encodeToString(data)
fun bDecode(string: String) = Base64.getDecoder().decode(string)
fun rsaEncrypt(keyFile: File, text: String): String {
val k = KeyFactory.getInstance("RSA").generatePublic(X509EncodedKeySpec(keyFile.readBytes()))
val c = Cipher.getInstance("RSA/ECB/OAEPwithSHA-512andMGF1Padding")
c.init(Cipher.ENCRYPT_MODE, k)
return bEncode(c.doFinal(text.toByteArray()))
}
fun rsaDecrypt(keyFile: File, ciphertext: String): String {
val k = KeyFactory.getInstance("RSA").generatePrivate(PKCS8EncodedKeySpec(keyFile.readBytes()))
val c = Cipher.getInstance("RSA/ECB/OAEPwithSHA-512andMGF1Padding")
c.init(Cipher.DECRYPT_MODE, k)
return c.doFinal(bDecode(ciphertext)).decodeToString()
}
根据我的文件,我首先运行 Python 文件,然后运行 Kotlin 文件。
这是在 Kotlin 中尝试解密 Python 加密数据时出现的错误。
线程“main”中的异常 javax.crypto.BadPaddingException:解密时填充错误 在 java.base/com.sun.crypto.provider.RSACipher.doFinal(RSACipher.java:389) 在 java.base/com.sun.crypto.provider.RSACipher.engineDoFinal(RSACipher.java:425) 在 java.base/javax.crypto.Cipher.doFinal(Cipher.java:2205) 在 TestKt.rsaDecrypt(test.kt:58) 在 TestKt.main(test.kt:22) 在 TestKt.main(test.kt)
这是尝试解密 Kotlin 加密数据时 Python 中出现的错误。
回溯(最近一次调用最后一次):文件“C:\Users\MYUSERNAME\Projects\MyServer\test.py”,第 53 行,在 <module> print("Decrypt", dec(inp[3:].strip())) ^^^^^^^^^^^^^^^^^^^^^ 文件“C:\Users\MYUSERNAME\Projects\MyServer\test.py”,第 40 行,在 dec return pk.decrypt( ^^^^^^^^^^^^ ValueError:解密失败
我的代码有什么问题?
代码执行如下。(我分别在 Python 和 Kotlin 中分别添加了加密数据的类型和大小的 print/println 语句,看起来正常。)
S C:\Users\USERNAME\Projects\MyServer> python test.py && kotlinc test.kt -include-runtime -d app.jar && kotlin app.jar
Loading existing keys
RSA: enc Hello
<class 'bytes'>
512
Encrypt sMeiZvcV5aHIFsW7+pOhcAwi/Jk1Fc0JevLM9U5LK+005vFgxUgVehLgwgMG/9TJ7wPOVYI51Cnrhc4aLBfG6gawWoc+NGO8WfGA7HF0xFgdDreAIzRMGOsR7AkoVBsBz7HbjnQ+3Nz1AOUHAUbrVLLizAvCjQAB0xbvv/YtQWRXrZOCEbF3+RFF9GOWQO8Lk8Wd/KvnD6pyASw8QvGqEJXL8aWZH0P8FDYUEcwjrz4qOgZDBce8qdiVf8h2FItm/AzeWvBuMai0FSh4SYjYMW2Ld8BGACsBIhYtpXG62WVULvXHK5oGQ5mpJz62WKCauDeqGdugeP9LVDA0k3Nd645hU6WCCA5o4VrKhz4WR4uN6ND42qNCIIE9LLMyHBGcZ+bOf0pGraLqbOHOYkD4bLD3j32ILT88WpC31KhFjvdCxBv81IXdl0/6f9U+q4d6ZZ9OiWjDdINemFVxgis9d1GzuTYzQ2i3MGudHfnFAMKjZWW8IJIfaIfAiMob/WjO2VTGvn0eFaUviszFaAfzTcoe0AnhyUpEEgu1KUcJk/CUoSnKYRX62T2wgmHKgfavdeKYmLPKugORRcCj9hlkke2rlTva0EP9970UycOwJGb92CwxPn68C8wA/jmKxoj7U2CDUArTwqV/dzvQ/gosfSSF/bWB9ZSoAi2//JVlk+g=
RSA: dec sMeiZvcV5aHIFsW7+pOhcAwi/Jk1Fc0JevLM9U5LK+005vFgxUgVehLgwgMG/9TJ7wPOVYI51Cnrhc4aLBfG6gawWoc+NGO8WfGA7HF0xFgdDreAIzRMGOsR7AkoVBsBz7HbjnQ+3Nz1AOUHAUbrVLLizAvCjQAB0xbvv/YtQWRXrZOCEbF3+RFF9GOWQO8Lk8Wd/KvnD6pyASw8QvGqEJXL8aWZH0P8FDYUEcwjrz4qOgZDBce8qdiVf8h2FItm/AzeWvBuMai0FSh4SYjYMW2Ld8BGACsBIhYtpXG62WVULvXHK5oGQ5mpJz62WKCauDeqGdugeP9LVDA0k3Nd645hU6WCCA5o4VrKhz4WR4uN6ND42qNCIIE9LLMyHBGcZ+bOf0pGraLqbOHOYkD4bLD3j32ILT88WpC31KhFjvdCxBv81IXdl0/6f9U+q4d6ZZ9OiWjDdINemFVxgis9d1GzuTYzQ2i3MGudHfnFAMKjZWW8IJIfaIfAiMob/WjO2VTGvn0eFaUviszFaAfzTcoe0AnhyUpEEgu1KUcJk/CUoSnKYRX62T2wgmHKgfavdeKYmLPKugORRcCj9hlkke2rlTva0EP9970UycOwJGb92CwxPn68C8wA/jmKxoj7U2CDUArTwqV/dzvQ/gosfSSF/bWB9ZSoAi2//JVlk+g=
Decrypt Hello
RSA:
Text: Hello
ByteArray
512
XgLJElQ46cqiVmwqs/j2y8NptEU9ciAnQFtuuh2U+4m1PbqatnzVrB//G6NXrH2hYbclj9GyHMAzRh3f9LlGozQl7FgvmGp6F38DD2j2ktVChAMLCWtw7GMkJlyJiINFdiYL1IV1EI/+DpQYzeE94tyQDaev053GAW+aFxymWTVSZ1uw97XJGCd1V2RRyzzPKirG/BTxKS+j9iqsGUCd+7SVghzhWlzZYgaPj+7t0by45SURvrtTdaD6Ni1FIwROPOzTEE6ryFbK0tPWECN1jnQI/1qylldE/N/Awqc0ORsj9wCITh80D2ibfZyr/AN5I+QOU3y4pfX76C6xAvsFt1Avsk15sktsNfrBC3+OyNB1PWiKmeXcxly2rx4PswpL56WEOkcrhF6GcyctfU5gJNDQ/CsND+u3/JNtPHtPdmAhwoY0UWeUeZWIp0yR42fbrLBgFzPodahHNXopMhBlGO84yzO6WNGbm/0lBnVSm6PAw6ti5N0gSC6eNq/odSQQYThVOvxJB9ETPbzX8CaV8GmQUbiGVzR8P5HOvYK4ctyIJha/X1rP4CpbKXsKVLYWuvGKJ1T7fG6/69/pKLJC3MkurpM2OVlb5UgV5W1A4fCQROQ9yTt4jRUllgmORvaUrOZO62rHKnFmA6cxRXou36t61HKYAmQ3ahq/ErBQyuI=
Ciphertext: XgLJElQ46cqiVmwqs/j2y8NptEU9ciAnQFtuuh2U+4m1PbqatnzVrB//G6NXrH2hYbclj9GyHMAzRh3f9LlGozQl7FgvmGp6F38DD2j2ktVChAMLCWtw7GMkJlyJiINFdiYL1IV1EI/+DpQYzeE94tyQDaev053GAW+aFxymWTVSZ1uw97XJGCd1V2RRyzzPKirG/BTxKS+j9iqsGUCd+7SVghzhWlzZYgaPj+7t0by45SURvrtTdaD6Ni1FIwROPOzTEE6ryFbK0tPWECN1jnQI/1qylldE/N/Awqc0ORsj9wCITh80D2ibfZyr/AN5I+QOU3y4pfX76C6xAvsFt1Avsk15sktsNfrBC3+OyNB1PWiKmeXcxly2rx4PswpL56WEOkcrhF6GcyctfU5gJNDQ/CsND+u3/JNtPHtPdmAhwoY0UWeUeZWIp0yR42fbrLBgFzPodahHNXopMhBlGO84yzO6WNGbm/0lBnVSm6PAw6ti5N0gSC6eNq/odSQQYThVOvxJB9ETPbzX8CaV8GmQUbiGVzR8P5HOvYK4ctyIJha/X1rP4CpbKXsKVLYWuvGKJ1T7fG6/69/pKLJC3MkurpM2OVlb5UgV5W1A4fCQROQ9yTt4jRUllgmORvaUrOZO62rHKnFmA6cxRXou36t61HKYAmQ3ahq/ErBQyuI=
Decrypted: Hello
PS C:\Users\USERNAME\Projects\MyServer> kotlin app.jar
Text: Hi
ByteArray
512
hS4WeVI6Vuh/bdyiDMvBtyYRBfRWHkSJsrmSe4ivq2Xov+3jRXMqxajPiJ6gH9qIB4U4pFa2sy0gdjM+fQtzqv86JPAvbGjO+fFYQhunvVwJwIlR/3fwUJRSkzaYNTR+SsZ4mTJKB45bwiurZuOQFfQ8e72cD+UBkAPJmFx5FftazKIis0ehwdJ+G3ZAnTwzPM82dqIQCMfb6JeeT2F7BLhdc06pKQXiWPDRytkDSHfOXf0SWJJ5Kwbgy6G10X68VRND/DsS3CXrxr2us8/9IrZZw2sCkE72MB38/sUSB5lwYeia5Rf3OxKzq1VQrHcI8obdIErVg7NNsKfSMdxA2pIHzZfFnu9by7gOw+hy95ntrdjE9RE9IcEt5ylZ0ZFmvCjnAJ1/TbqhZBN70blxMJDrqiYoM0x/M3EjdTuodlJ+deNZI84mfAmCmzDTj2umFT6X0HKFJPQVaZYDIyDq+EJueYOdS3xKHfE2ycWkQSPh9lmebA1GNuv6EgGMMiEkw86mFvAHe9jgSkYkLI7+qMjARuJLTYXKINihVRDyyzcMAq7eDuFDoVWavNu/cw5AXJO8TZzSGTFtoLgfXpck1BKfnrb3IEe01pqADJArX3hgCB22xLEZ9zktj71L1T/gHrEfMM4bnJkpyvVEDm9kajMIwFZa3hq8FztoDkNzbFI=
Ciphertext: sMeiZvcV5aHIFsW7+pOhcAwi/Jk1Fc0JevLM9U5LK+005vFgxUgVehLgwgMG/9TJ7wPOVYI51Cnrhc4aLBfG6gawWoc+NGO8WfGA7HF0xFgdDreAIzRMGOsR7AkoVBsBz7HbjnQ+3Nz1AOUHAUbrVLLizAvCjQAB0xbvv/YtQWRXrZOCEbF3+RFF9GOWQO8Lk8Wd/KvnD6pyASw8QvGqEJXL8aWZH0P8FDYUEcwjrz4qOgZDBce8qdiVf8h2FItm/AzeWvBuMai0FSh4SYjYMW2Ld8BGACsBIhYtpXG62WVULvXHK5oGQ5mpJz62WKCauDeqGdugeP9LVDA0k3Nd645hU6WCCA5o4VrKhz4WR4uN6ND42qNCIIE9LLMyHBGcZ+bOf0pGraLqbOHOYkD4bLD3j32ILT88WpC31KhFjvdCxBv81IXdl0/6f9U+q4d6ZZ9OiWjDdINemFVxgis9d1GzuTYzQ2i3MGudHfnFAMKjZWW8IJIfaIfAiMob/WjO2VTGvn0eFaUviszFaAfzTcoe0AnhyUpEEgu1KUcJk/CUoSnKYRX62T2wgmHKgfavdeKYmLPKugORRcCj9hlkke2rlTva0EP9970UycOwJGb92CwxPn68C8wA/jmKxoj7U2CDUArTwqV/dzvQ/gosfSSF/bWB9ZSoAi2//JVlk+g=
Exception in thread "main" javax.crypto.BadPaddingException: Padding error in decryption
at java.base/com.sun.crypto.provider.RSACipher.doFinal(RSACipher.java:389)
at java.base/com.sun.crypto.provider.RSACipher.engineDoFinal(RSACipher.java:425)
at java.base/javax.crypto.Cipher.doFinal(Cipher.java:2205)
at TestKt.rsaDecrypt(test.kt:59)
at TestKt.main(test.kt:22)
at TestKt.main(test.kt)
PS C:\Users\USERNAME\Projects\MyServer> python test.py
Loading existing keys
RSA: dec XgLJElQ46cqiVmwqs/j2y8NptEU9ciAnQFtuuh2U+4m1PbqatnzVrB//G6NXrH2hYbclj9GyHMAzRh3f9LlGozQl7FgvmGp6F38DD2j2ktVChAMLCWtw7GMkJlyJiINFdiYL1IV1EI/+DpQYzeE94tyQDaev053GAW+aFxymWTVSZ1uw97XJGCd1V2RRyzzPKirG/BTxKS+j9iqsGUCd+7SVghzhWlzZYgaPj+7t0by45SURvrtTdaD6Ni1FIwROPOzTEE6ryFbK0tPWECN1jnQI/1qylldE/N/Awqc0ORsj9wCITh80D2ibfZyr/AN5I+QOU3y4pfX76C6xAvsFt1Avsk15sktsNfrBC3+OyNB1PWiKmeXcxly2rx4PswpL56WEOkcrhF6GcyctfU5gJNDQ/CsND+u3/JNtPHtPdmAhwoY0UWeUeZWIp0yR42fbrLBgFzPodahHNXopMhBlGO84yzO6WNGbm/0lBnVSm6PAw6ti5N0gSC6eNq/odSQQYThVOvxJB9ETPbzX8CaV8GmQUbiGVzR8P5HOvYK4ctyIJha/X1rP4CpbKXsKVLYWuvGKJ1T7fG6/69/pKLJC3MkurpM2OVlb5UgV5W1A4fCQROQ9yTt4jRUllgmORvaUrOZO62rHKnFmA6cxRXou36t61HKYAmQ3ahq/ErBQyuI=
Traceback (most recent call last):
File "C:\Users\USERNAME\Projects\MyServer\test.py", line 56, in <module>
print("Decrypt", dec(inp[3:].strip()))
^^^^^^^^^^^^^^^^^^^^
File "C:\Users\USERNAME\Projects\MyServer\test.py", line 43, in dec
return pk.decrypt(
^^^^^^^^^^^
ValueError: Decryption failed