V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
The Go Programming Language
http://golang.org/
Go Playground
Go Projects
Revel Web Framework
awanganddong
V2EX  ›  Go 编程语言

golang 怎么实现 rsa 加解密

  •  
  •   awanganddong · 147 天前 · 2448 次点击
    这是一个创建于 147 天前的主题,其中的信息可能已经有所发展或是发生改变。

    一般是公钥加密,私钥解密。 但是这份代码,需要私钥加密,公钥解密。

    下边是 php 代码,公钥解密

    function public_key_decrypt($data, $public_key)
    {
        $public_key = '-----BEGIN PUBLIC KEY-----' . "\n" . $public_key . "\n" . '-----END PUBLIC KEY-----';
        $data = base64_decode($data);
        $pu_key = openssl_pkey_get_public($public_key);
        $crypto = '';
        foreach (str_split($data, 128) as $chunk) {
            openssl_public_decrypt($chunk, $decryptData, $pu_key);
            $crypto .= $decryptData;
        }
    
        return $crypto;
    }
    

    用 chatgpt 转化为 golang 的时候代码有问题。 想问下该怎么处理。

    func (t *TopPayService) rsaPublicDecrypt(publicKey *rsa.PublicKey, encryptedData []byte) ([]byte, error) { // 使用 RSA OAEP 解密 decryptedData, err := rsa.DecryptOAEP( sha256.New(), // 使用 SHA-256 作为哈希函数 rand.Reader, // 随机数生成器 publicKey, // 公钥 encryptedData, // 加密的数据 nil, // 可选的 label ,默认为 nil ) if err != nil { return nil, err } return decryptedData, nil }

    14 条回复    2024-07-05 09:44:56 +08:00
    awanganddong
        2
    awanganddong  
    OP
       147 天前
    @hellolinuxer 我需要的是公钥解密
    awanganddong
        3
    awanganddong  
    OP
       147 天前
    go get github.com/farmerx/gorsa
    找到了这个扩展
    GTim
        4
    GTim  
       147 天前
    HFX3389
        5
    HFX3389  
       147 天前 via iPhone
    @awanganddong 传说中的变态模式,私钥加密公钥解密
    pagxir
        6
    pagxir  
       147 天前
    RSA 的密钥是成对的,不存在那个就必须是公钥,那个就是私钥。都是人为指定的。
    DefoliationM
        7
    DefoliationM  
       147 天前 via Android
    一样的,本来是公钥加密私钥解密,你现在反过来了,那还是用公钥加密当解密用,只是个函数名而已。
    iceheart
        8
    iceheart  
       147 天前 via Android   ❤️ 3
    私钥加密公钥解密,与签名等效
    wen20
        9
    wen20  
       147 天前
    ```
    func Encrypt(plainText, publicKey []byte) (cryptText []byte, err error) {
    block, _ := pem.Decode(publicKey)

    key, err := x509.ParsePKIXPublicKey(block.Bytes)
    if err != nil {
    return []byte{}, err
    }
    cryptText, err = rsa.EncryptPKCS1v15(rand.Reader, key.(*rsa.PublicKey), plainText)
    if err != nil {
    return []byte{}, err
    }
    return cryptText, nil
    }

    ```
    rickiey
        10
    rickiey  
       147 天前
    私钥加密,公钥解密,这叫数字签名
    rickiey
        11
    rickiey  
       147 天前
    一般公钥解密叫验证私钥的签名,如果是向指定公钥传递加密信息应该考虑密钥协商,再一个 RSA 太长了,建议换 ed25519 或者类似的短一点的加密方式
    sophos
        12
    sophos  
       147 天前
    让我想起很久以前写的 rsa 库,为了用 go 重构 php 中历史代码的加解密逻辑,不得不自己写一套...应该还能用

    https://github.com/sysulq/rsa
    awanganddong
        13
    awanganddong  
    OP
       146 天前
    谢谢大家,@sophos 你写的我让 chatgpt 给解析下
    awanganddong
        14
    awanganddong  
    OP
       146 天前
    这个代码实现了 RSA 加密和解密的一些功能,以下是对代码的详细解释:

    错误定义
    定义了一些可能会在 RSA 加密/解密过程中遇到的错误:

    ErrDataToLarge:
    ErrDataLen:
    ErrDataBroken:
    ErrKeyPairDismatch:
    ErrDecryption:
    ErrPublicKey:
    ErrPrivateKey: 获取私钥错误。
    公钥解密函数
    pubKeyDecrypt
    用公钥解密数据:

    计算模数的字节长度,并检查数据长度是否符合要求。
    将数据转换为大整数,并检查数据是否超出模数的范围。
    通过模幂运算解密数据。
    去掉填充字节,返回解密后的数据。
    LeftUnPad
    去掉左边的填充字节:

    检查第一个字节是否为 0 。
    检查第二个字节是否为 0 或 1 。
    找到第一个非零字节的索引,返回剩余的数据。
    RightUnPad
    去掉右边的填充字节:

    从右边开始找到第一个非零字节的索引,返回剩余的数据。
    私钥加密函数
    priKeyEncrypt
    用私钥加密数据:

    计算模数的字节长度,检查数据长度是否符合要求。
    创建加密的消息,填充数据。
    通过模幂运算加密数据,返回加密后的数据。
    公钥和私钥加密/解密读写器
    pubKeyIO
    用公钥进行加密或解密:

    根据是否加密,调整块大小。
    读取数据块,加密或解密数据块,写入输出。
    priKeyIO
    用私钥进行加密或解密:

    根据是否加密,调整块大小。
    读取数据块,加密或解密数据块,写入输出。
    公钥和私钥加密/解密字节数组
    PubKeyByte
    用公钥加密或解密字节数组:

    根据是否加密,调整块大小。
    如果数据长度小于块大小,直接加密或解密。
    否则,通过读写器进行处理,返回处理后的数据。
    PriKeyByte
    用私钥加密或解密字节数组:

    根据是否加密,调整块大小。
    如果数据长度小于块大小,直接加密或解密。
    否则,通过读写器进行处理,返回处理后的数据。
    获取公钥和私钥函数
    GetPubKey
    从 Base64 编码的字符串中读取公钥:

    解码 Base64 字符串,调用 GetPubKeyFromPem 解析 PEM 格式的公钥。
    GetPubKeyFromPem


    解码 PEM 格式的公钥,解析成 RSA 公钥。
    GetPriKey
    从 Base64 编码的字符串中读取私钥:

    解码 Base64 字符串,调用 GetPriKeyFromPem 解析 PEM 格式的私钥。
    GetPriKeyFromPem
    从 PEM 格式的字节数组中读取私钥:

    解码 PEM 格式的私钥,解析成 RSA 私钥。
    内部工具函数
    encrypt
    加密函数,执行模幂运算。

    decrypt
    解密函数,执行模幂运算。

    copyWithLeftPad
    在左边填充 0 以适应指定大小。

    nonZeroRandomBytes
    生成非零的随机字节。

    leftPad
    在左边填充字节以适应指定大小。

    modInverse
    计算

    这些函数和方法共同实现了 RSA 公钥加密、私钥解密、私钥加密、公钥解密的功能,包括读取和解析公钥/私钥文件,处理填充和数据块的分割等。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   3461 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 31ms · UTC 11:01 · PVG 19:01 · LAX 03:01 · JFK 06:01
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.