我的任务是实现RSA算法的图像加密。我正在生成RSA参数,然后从文件加载图像,进行加密,解密,然后将新图像保存到文件。问题是,当显示图像时,图像的底部似乎已损坏且未很好地解密。你有什么想法我的代码有什么问题吗?
from PIL import Image
import io
from Crypto.Util.number import long_to_bytes
from Crypto.Util.number import inverse
from Crypto.Util.number import getPrime
from Crypto.Util.number import GCD
from Crypto.Util.number import bytes_to_long
from Crypto.Util.number import getRandomRange
blockSize = 255
def loadImage():
with io.BytesIO() as recivedPicture:
with Image.open("IMG2.jpg") as picture:
picture.save(recivedPicture, 'JPEG')
returnVal = recivedPicture.getvalue()
return returnVal
def saveImage(decryptedImg):
picture = Image.open(io.BytesIO(decryptedImg))
picture.save("rsa_photo_copy.jpg", picture.format)
print("Hacking procedure finished success!\n")
def proceedRSA(n, e, d):
eByteArray = bytearray()
dByteArray = bytearray()
print("Hacking procedure begin\n")
for i in range(0, len(loadImage()), blockSize):
blockData = loadImage()[i:i + blockSize]
eByteArray.extend(encryptFunction(blockData, e, n))
dByteArray.extend(decryptFunction(encryptFunction(blockData, e, n), d, n))
saveImage(dByteArray)
def encryptFunction(data, e, n):
m = bytes_to_long(data)
c = pow(m, e, n)
value = long_to_bytes(c)
return value
def decryptFunction(data, d, n):
c = bytes_to_long(data)
m = pow(c, d, n)
value = long_to_bytes(m)
return value
def main():
# odnalezienie 1024 bitowej liczby pierwszej q
q = getPrime(1024)
# odnalezienie 1024 bitowej liczby pierwszej p
p = getPrime(1024)
# powtórzenie losowania p tak długo jak p jest różne od q
while q==p:
p = getPrime(1024)
pass
# znalezienie n = p*q
n = p * q
# znalezienie f = (p-1) * (q-1)
f = (p - 1) * (q - 1)
# znalezienie e
e = getRandomRange(1, f - 1)
while GCD(e, f) != 1:
e = getRandomRange(1, f - 1)
# znalezienie d
d = inverse(e, f)
# wywołanie algorytmu
proceedRSA(n, e, d)
if __name__ == "__main__":
main()
答案 0 :(得分:0)
普通/教科书RSA完全不安全。
但是,作为一种实践,您应该知道您确实不能为2048位密钥加密256个字节的随机数据,因为作为无符号大整数的值可能大于模数。但是,结果通常需要256个字节。因此,明文的块大小必须小于密文的块大小。
如果可以拆分单个位,将避免这种情况,因为只有最高位必须比1多0。但是,是的,没有这种运气,位比原子更原子。
您可以通过调试代码来找出答案。