推荐学习书目
› Learn Python the Hard Way
Python Sites
› PyPI - Python Package Index
› http://diveintopython.org/toc/index.html
› Pocoo
值得关注的项目
› PyPy
› Celery
› Jinja2
› Read the Docs
› gevent
› pyenv
› virtualenv
› Stackless Python
› Beautiful Soup
› 结巴中文分词
› Green Unicorn
› Sentry
› Shovel
› Pyflakes
› pytest
Python 编程
› pep8 Checker
Styles
› PEP 8
› Google Python Style Guide
› Code Style from The Hitchhiker's Guide
simple2025
0D
V2EX  ›  Python

今天碰到一个对接 Java rsa pkcs1 用公钥解密,

  •  
  •   simple2025 · Jun 11, 2021 · 4180 views
    This topic created in 1980 days ago, the information mentioned may be changed or developed.

    python 我搜了好久,都是用私钥解密的, 论坛里的大佬有给个资料的吗?

    我实在搜不到了

    Supplement 1  ·  Jun 13, 2021
    私钥加密卡死了

    私钥加密的东西, 用公钥解密不出来

    把私钥就加密的 base64, 放网上也解密不出来

    代码::

    ```


    def util_rsa_encrypt_by_privatekey(private_key_str, raw_message, block_size=117):
    """
    Args:
    private_key_str: 没有'---'的密钥, 可以是多行
    raw_message: 应该是 byte
    Returns:
    (str): base64 之后的结果
    """
    assert isinstance(raw_message, bytes)
    private_key_str = "".join(private_key_str.splitlines())
    private_key_str = handle_pri_key(private_key_str)
    priv_key = rsa.PrivateKey._load_pkcs1_pem(private_key_str)
    keylength = common.byte_size(priv_key.n)

    block_list = []
    raw_message_len = len(raw_message)
    for i in range(0, raw_message_len, block_size):
    message = raw_message[i:i + block_size]
    padded = _pad_for_encryption(message, keylength)

    payload = transform.bytes2int(padded)
    encrypted = core.encrypt_int(payload, priv_key.d, priv_key.n)
    block = transform.int2bytes(encrypted, keylength)
    block_list.append(block)
    byte_str = b''.join(block_list)
    b64_str = base64.b64encode(byte_str).decode("utf-8")
    return b64_str
    ```

    求指点
    21 replies  •  2021-06-15 20:33:11 +08:00
    zvcs
    zvcs
    Jun 11, 2021 via iPhone❤️1
    1
    公钥不也是私钥吗?
    GM
    GM
    Jun 11, 2021❤️1
    2
    对于一对公钥、私钥:
    公钥加密了,可以用对应的私钥解密。
    私钥加密了,可以用对应的公钥解密。
    LLaMA2
    LLaMA2
    Jun 11, 2021❤️1
    3
    记住口诀,公加私解,私加公验
    66Zi2nJk5Z6mdtzj
    66Zi2nJk5Z6mdtzj
    Jun 11, 2021 via iPhone❤️1
    4
    公钥那个不叫解密,叫验证。从知乎看来的~

    加密的时候,肯定不希望别人能看到解密过后的内容,所以就只能用私钥解密,对应就是公钥加密。

    反过来,当有个东西我希望别人能验证就是属于我这个私钥,而不是别人的私钥那就是私钥签名,公钥验证
    godblessumilk
    godblessumilk
    Jun 12, 2021 via Android❤️1
    5
    理论上无论公钥加密还是私钥加密都是可以的,只是用私钥加密,能作简单的身份认证(用私钥加密明文,生成数字签名)
    simple2025
    simple2025
    OP
    Jun 12, 2021
    6
    @yuanmomo 但是我用 python 搞不了呀, 因为我对接的 java, 他用私钥加密的, 所以我用公钥解密, 但是试了好久都不行呀,
    求指点
    zonghow
    zonghow
    Jun 12, 2021 via iPhone
    7
    M2Crypto 可以 关键 api:public_decrypt
    liuidetmks
    liuidetmks
    Jun 12, 2021 via iPhone
    8
    rsa 的话,公钥解密叫签名验证。

    别人用私钥加密,你用公钥能解开 就能证明是他发的内容了。
    xiangyuecn
    xiangyuecn
    Jun 12, 2021
    9
    本质上是没毛病的😂 N E D 三个数,NE 、ND 随便哪个做公钥,另外一个就是私钥

    不过有一个问题,比较标准的密钥生成工具,指定了 N 后,E 一般给的就是 AQAB=65537,据说是因为这个数加密更快。然后,这样的固定的 E 只能是做公钥😂

    附我几年前写的从 pem 中提取 N 、E 、D 的代码(纯字节码解析):

    C#: https://github.com/xiangyuecn/RSA-csharp

    Java: https://github.com/xiangyuecn/RSA-java

    Python: - 🤷‍♂️
    simple2025
    simple2025
    OP
    Jun 12, 2021
    10
    @zonghow 我试试 m2crypto
    simple2025
    simple2025
    OP
    Jun 12, 2021
    11
    @zonghow 但是我 centos7 怎么装 `M2Crypto` 呀
    simple2025
    simple2025
    OP
    Jun 12, 2021
    12
    @zonghow 关键我还是用的 pyenv 装的 python3, 早知道用 ubuntu 了
    simple2025
    simple2025
    OP
    Jun 12, 2021
    13
    大佬们给个 python 私钥加密, 公钥解密的例子把, 我也不想私钥加密,公钥解密的呀, 但是对接就是这个样子呀, 大佬们, 帮帮忙把
    openmm
    openmm
    Jun 12, 2021
    14
    哈哈哈哈 专业点叫私钥签名 公钥验签 虽然原理上也是加解密 但用途上目的不是为了加密 而是为了验证
    simple2025
    simple2025
    OP
    Jun 12, 2021
    15
    @openmm 不, 就是公钥解密, 他平台自己保留私钥, 他给我的内容是私钥加密的, 所以我这边需要公钥解密
    LLaMA2
    LLaMA2
    Jun 12, 2021
    16
    把密文和公钥发来,大伙给你验证下
    simple2025
    simple2025
    OP
    Jun 12, 2021
    17
    我左搜右搜,终于找到解密, 现在要搞私钥加密了
    among
    among
    Jun 15, 2021
    18
    class MyRsa():
    def __init__(self, pri_key_file, pub_key_file):
    with open(pri_key_file, mode='rb') as privatefile:
    private_keydata = privatefile.read()
    self.privkey = rsa.PrivateKey.load_pkcs1(private_keydata)
    with open(pub_key_file, mode='rb') as publicfile:
    public_keydata = publicfile.read()
    self.pubkey = rsa.PublicKey.load_pkcs1(public_keydata)

    def encrypt_b64(self, msg):
    crypto_text = rsa.sign(msg.encode('utf8'), self.privkey, 'SHA-1')
    res = base64.b64encode(crypto_text)
    res = res.decode()
    logz.info(msg)
    # logz.info(self.privkey)
    logz.info(res)
    return res



    rsa1 = MyRsa(pri_key_file=pri_key_file, pub_key_file=pub_key_file)
    signature = rsa1.encrypt_b64(sign_str)
    print(signature)


    试试,拷贝了一段。
    simple2025
    simple2025
    OP
    Jun 15, 2021
    19
    @among 我用 M2Crypto 实现了, 就是我的 python 需要重装
    among
    among
    Jun 15, 2021
    20
    @chenqh

    问题解决了,是不是也需要贴个 代码出来。。
    simple2025
    simple2025
    OP
    Jun 15, 2021
    21
    @among


    ```
    import M2Crypto
    from tornado import escape
    import base64
    """
    sudo yum install -y python3-devel openssl-devel swig
    pip install M2Crypto
    """

    def handle_key_inner(key, start, end):
    result = ''
    # 分割 key,每 64 位长度换一行
    divide = int(len(key) / 64)
    divide = divide if (divide > 0) else divide + 1
    line = divide if (len(key) % 64 == 0) else divide + 1
    for i in range(line):
    result += key[i * 64:(i + 1) * 64] + '\n'
    result = start + result + end
    return result


    def handle_pub_key(key):
    """
    处理公钥
    公钥格式 pem,处理成以-----BEGIN PUBLIC KEY-----开头,-----END PUBLIC KEY-----结尾的格式
    :param key:pem 格式的公钥,无-----BEGIN PUBLIC KEY-----开头,-----END PUBLIC KEY-----结尾
    :return:
    """
    start = '-----BEGIN PUBLIC KEY-----\n'
    end = '-----END PUBLIC KEY-----'
    return handle_key_inner(key, start, end)


    def handle_pri_key(key):
    start = '-----BEGIN PRIVATE KEY-----\n'
    end = '-----END PRIVATE KEY-----'
    return handle_key_inner(key, start, end)


    def util_rsa_encrypt_with_private_key_str(msg: bytes, private_key_str: str, blocksize=117):
    private_key_str = "".join([e.strip() for e in private_key_str.splitlines()])
    private_key_str = handle_pri_key(private_key_str)
    bio = M2Crypto.BIO.MemoryBuffer(private_key_str.encode("utf-8"))
    rsa_pri = M2Crypto.RSA.load_key_bio(bio)
    out_li = []
    len_msg = len(msg)
    for i in range(0, len_msg, blocksize):
    piece = msg[i:i + blocksize]
    ctxt_pri = rsa_pri.private_encrypt(piece, M2Crypto.RSA.pkcs1_padding) # 这里的方法选择加密填充方式,所以在解密的时候 要对应。
    out_li.append(ctxt_pri)
    raw_msg = b''.join(out_li)
    return base64.b64encode(raw_msg)


    def pub_decrypt_with_pubkeyfile(msg, file_name):
    rsa_pub = M2Crypto.RSA.load_pub_key(file_name)
    pub_decrypt(msg, rsa_pub)


    def util_rsa_decrypt_with_public_key_str(msg, pub_key: str):
    """
    Args:
    msg: base64 string
    """
    pub_key = "".join([e.strip() for e in pub_key.splitlines()])
    pub_key = handle_pub_key(pub_key)
    msg = escape.utf8(msg)
    bio = M2Crypto.BIO.MemoryBuffer(pub_key.encode("utf-8"))
    rsa_pub = M2Crypto.RSA.load_pub_key_bio(bio)
    return pub_decrypt(msg, rsa_pub)


    def pub_decrypt(msg, rsa_pub, block_size=128):

    ctxt_pri = base64.b64decode(msg) # 先将 str 转成 base64
    # maxlength = 128
    li = []
    len_ctxt = len(ctxt_pri)
    for i in range(0, len_ctxt, block_size):
    input = ctxt_pri[i:i + block_size]
    out = rsa_pub.public_decrypt(input, M2Crypto.RSA.pkcs1_padding) # 解密
    li.append(out)
    return b''.join(li)

    ```
    About   ·   Help   ·   Advertise   ·   Blog   ·   API   ·   FAQ   ·   Privacy   ·   Solana   ·   1419 Online   Highest 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 49ms · UTC 16:54 · PVG 00:54 · LAX 08:54 · JFK 11:54
    ♥ Do have faith in what you're doing.