python rsa実践

12643 ワード

最近pythonで長い接続のものを書いていて、2、3週間前にpythonに触れ始めたばかりなので、ずっと本を読んでいて、コードを書くのが少し苦しくて、基本的にひざまずいて模索しています.前のブログのprotobuf(前にandroidを書いたのはjsonを迎えただけなので、これには概念がありません)だからgithubでreadmeを見るしかありません.readmeは長いですね.ドキュメントに合わせて1時間以上見て、コードを引いて2時間以上引いて、ここ数日pythonを書くのは基本的にこの状態です....pythonのRSAは実用的で簡単で、ドキュメントを見つけてから解決しました.
https://www.dlitz.net/software/pycrypto/api/2.6/
简単に包んで、サーバーは直接neを要したので、ne私はすべて出して、コードは以下の通りです

# https://www.dlitz.net/software/pycrypto/api/2.6/

import ast
from Crypto.PublicKey import RSA
from Crypto import Random
from codecs import encode
from Crypto.PublicKey.RSA import construct
from binascii import unhexlify


class RSAUtil(object):
    def __init__(self):
        self._key = None
        self._public_key = None
        self._n = None
        self._e = None

    def generate(self):
        random_generator = Random.new().read
        self._key = RSA.generate(1024, random_generator)
        self._public_key = self._key.publickey()
        self._n = self._key.n
        self._e = self._key.e

    def create(self, modulus, public_exponent):
        self._e = int(public_exponent)
        self._n = modulus
        self._public_key = construct((int(encode(modulus, 'hex'), 16), public_exponent))

    def public_key(self):
        return self._public_key.exportKey()

    def private_key(self):
        if self._key is None:
            raise ValueError("not private key,func generate() should be call before this")
        return self._key.exportKey()

    def public_exponent(self):
        if self._e is None:
            raise ValueError("not private key,func generate() should be call before this")
        return self._e

    def modulus(self):
        if self._n is None:
            raise ValueError("not private key,func generate() should be call before this")
        return str(self.long_to_bytes(self._n))

    def encode(self, data):
        if self._public_key is None:
            raise ValueError("not private key,func generate() should be call before this")
        return self._public_key.encrypt(data, None)[0]

    def decode(self, encrypts):
        if self._key is None:
            raise ValueError("not private key,func generate() should be call before this")
        temp = (encrypts,)
        return self._key.decrypt(ast.literal_eval(str(temp)))

    def long_to_bytes(self, value, endianness='big'):
        # https://stackoverflow.com/questions/8730927/convert-python-long-int-to-fixed-size-byte-array
        width = value.bit_length()
        width += 8 - ((width % 8) or 8)
        fmt = '%%0%dx' % (width // 4)
        s = unhexlify(fmt % value)
        if endianness == 'little':
            # see http://stackoverflow.com/a/931095/309233
            s = s[::-1]
        return s


テストコード:
if __name__ == "__main__":
    # from Tool import RSAUtil
    t = RSAUtil()
    t.generate()
    raw = "hello yeshen"

    # encode
    print raw
    transfer = t.encode(raw)

    # decode
    print transfer
    print t.decode(transfer)

    # clone
    clone = RSAUtil()
    clone.create(t.modulus(), t.public_exponent())
    transfer_clone = clone.encode(raw)
    print transfer_clone
    print t.decode(transfer_clone)

出力:
hello yeshen                                                                                                                                                                                                                                                        V��Y�j�����8���޷��yd�C%%
I5��5b�� ��n���S?ƭ#l���/����(�����`����(8�%
I5��5b�� ��n���S#l���/����(�����`����(8�
hello yeshen

もし上のこれが使えないならば、别の1つの実现を使うべきです!!!
from codecs import encode
from Crypto.PublicKey.RSA import construct
from binascii import unhexlify
import rsa


class RSAUtil(object):
    def __init__(self):
        self._public_key = None
        self._private_key = None
        self._n = None
        self._e = None

    def generate(self):
        public_key, private_key = rsa.newkeys(1024)
        self._public_key = public_key
        self._private_key = private_key
        self._n = public_key.n
        self._e = public_key.e

    def create(self, modulus, public_exponent):
        self._e = int(public_exponent)
        self._n = modulus
        self._public_key = construct((int(encode(modulus, 'hex'), 16), public_exponent))

    def public_exponent(self):
        if self._e is None:
            raise ValueError("not private key,func generate() should be call before this")
        return self._e

    def modulus(self):
        if self._n is None:
            raise ValueError("not private key,func generate() should be call before this")
        return str(self.long_to_bytes(self._n))

    def decode(self, encrypts):
        if self._private_key is None:
            raise ValueError("not private key,func generate() should be call before this")
        return rsa.decrypt(encrypts, self._private_key)

    def long_to_bytes(self, value, endianness='big'):
        # https://stackoverflow.com/questions/8730927/convert-python-long-int-to-fixed-size-byte-array
        width = value.bit_length()
        width += 8 - ((width % 8) or 8)
        fmt = '%%0%dx' % (width // 4)
        s = unhexlify(fmt % value)
        if endianness == 'little':
            # see http://stackoverflow.com/a/931095/309233
            s = s[::-1]
        return s