关于前端加密服务端解迷讨论。安全? 不安全? 密钥(公钥)在此,谁来解谜[🫤]

这里不是讨论逆向,讨论的是加密安全。也不讨论获取公钥后的参数伪造。

  • 如果你认为前端加密,后端解谜后端解谜是安全的,并知道什么样的加解密是安全的可以跳过本文。否则看下一条
  • 如果你认为采用rsa非对称加密的方案的,前端加密,后端解密是安全的,可以跳过本文。否则可以对下文进行实验。

本文只做前端加密,后端解谜安全讨论。不讨流量论劫持下伪造等扩散话题。

今天暂时不放私钥

先放公钥

-----BEGIN RSA PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAtcvu2nHFH+ouUIcUyQHC
0oeSG9RONFssDvRgmAcFtGEuLuayAZjo5U1I7OFwSBdC+TssL5N+fasdMTG/Hs7Q
82gkEGy4QnaY7f2XDq3Y72EsKyCotyG3vHvfpv5fMspHOwJcwVFwQw6elOJOzBeJ
GloLr+j6fdgsa56GOOaqvZyxfUj862RxXEoYCE3nn01CPmfmF2lAqGamgLaKDICr
B3h1D0RO8ybLMpKN7FAXv4XpVLSxZroMrUmVBbiV2HjffMUKlxc22OWg+h4r/GEk
5UMVV4g3ccS/KmC5Y0sB5lfbv+U85IFmrjBhvEEvaH4QL0UdEYp0e7EEGe6VoU7J
bQIDAQAB
-----END RSA PUBLIC KEY-----

这是一个经过了rsa加密后,base64编码后展示的字符串,用的就是上述公钥。
感兴趣的同学可以看看只有公钥能不能获得原文。

I1L6yT66rAoq92g1khaMfzOLYbrJ6KGpe8Q4WGSia8gZiXPznIqsE+PTJJ8p9+dzpwbsloKax5faLcXz1zczVUvuap/Ef1856i3UgV/Ukz7dKVAjlT61VoU7pHe3rzP7tw/oy75nn6lF6AYqzhN66jEZNjwqSxfqP1XLBhWo0piXt6SbHHovD3yslWtRhnu3jKx+bzYpLOOLziCcAEOSIZz0IF00WN8xlRD1UnKMprNfQl2Lz0r6++I0oiRHsZkxG3qiVbOP8KptwtbXqtq2eBVxaDZ323d/mdlv24cLo6UtC6IQAgTUxd+1bEzKMgLqIzus5czUqZQQZnTCDbFd6Q==

以下3个字符串经过了rsa加密后,base64编码后展示,用的就是上述公钥。
他们的原始文本都是 Hello, RSA!

`IBAig/wzGocoG1odyF9aRqqwp4UtD4I9SydgaRV3l1MOWYLmrWdtotr+W+rVVKgXv1f/8XU+YdOKq4Hppqu2Imf/pMFPmuAZUfG+Rrwg9sf87JR70lHEx4uG9hXldubb+uL8pU/+ogoE8E78cBCpFuEE0gFUqgMkX0sttKwOs3McCfiE6ni49GMYEW3pReBPQ78C50H2Lgo1j8Uh77M6EZoHj1Dn8Mu7youZZAAXTH+8o7l5csFLqlTUULXMgOuBc9N6jJ9na7MhYaz7freK18l7na1ATDFZc3gITaThehW4rFNpPr9IvKuBw+NDirgn0Olq9H/mPm3fHfxAhLCQxw==`,
        `rQevqTepeouWxRDy7QyoRLOCguQk3ZGWLUW5T/IELQfIRJk80CxFC0Bs9Fq+wGFVg+qjF6k5LLi4RMk0gYfj7WHoZHzFb2Z3x3JFZ1h3c/w9Aig/bOkozOi7qWqDUdPcX5sna8tm9p3VhdFsTsdfZBbaqkRIUPO5HgJfXEnNYMwUze1COpclm3EHAMBlo8gSpS7znFEQmvhnjIq52PG180/rSljdLSTsMs7Co+HKcrRW9cowQt4fl19x4SDcDVVrOGEM1Rv7itf0Zo5GSMJnQ16MWGG1T3sIsJ6IsaZey7xF3Xew33vYm+cqjM1o5omZa0buu4iSkBZIeSfSHxLRFg==`,
        `fXSS3j5Lcb1PkIoClfPRCscmBIkbQ6LAKUIcs7a3fubWodmCmN/ZT8NEVheo7D4DcIo97ATQhxlcJeZzIqJRRY+9PoEp2FRP7sXOf1OmC4YHrYuPCd+XnY1XEEYERFQlUNNgckhGPkq3p832SV4RnZDvNcJspa8suk+ZpAu8P03mn9R49QOmQH65ldqG+11coqxFOgH08qjeE6IfJHjFtXrbGQ7UzTOQg7PwEOj6VbJ2BG3Vobh80XqWNab5iquqsaNsWu0mXujzdagUbnG8PXvsUk+LFh7Zw0XVe1y07zhB9qMrvVkYdeTe556jTMQ6lkzU+X6aiQ9DBtDETa9weA==`,

go 执行代码

详细代码

func runRsa(cmd *cobra.Command, args []string) {
    // param, _ := cmd.Flags().GetString("param")

    privatePemPath := filepath.Join("storage", "rsa", "private.pem")
    publicPemPath := filepath.Join("storage", "rsa", "public.pem")

    privateKey, err := generateKeyPair(2048)
    if err != nil {
        panic(err)
    }

    if !fileopt.IsExist(privatePemPath) || !fileopt.IsExist(publicPemPath) {
        fmt.Println("run?")
        fmt.Println(!fileopt.IsExist(privatePemPath), !fileopt.IsExist(publicPemPath))
        if err := savePrivateKey(privateKey, privatePemPath); err != nil {
            panic(err)
        }

        pub := &privateKey.PublicKey
        if err := savePublicKey(*pub, publicPemPath); err != nil {
            panic(err)
        }
    }

    // 加载公钥进行加密
    loadedPub, err := loadPublicKey(publicPemPath)
    if err != nil {
        panic(err)
    }

    plaintext := []byte("Hello, RSA!")
    ciphertext, err := encryptAndBase64Encode(loadedPub, plaintext)
    if err != nil {
        panic(err)
    }
    fmt.Printf("Ciphertext: %v\n", ciphertext)

    // 加载私钥进行解密
    loadedPriv, err := loadPrivateKey(privatePemPath)
    if err != nil {
        panic(err)
    }

    decryptedText, err := base64DecodeAndDecrypt(loadedPriv, ciphertext)
    if err != nil {
        panic(err)
    }
    fmt.Printf("Decrypted text: %s\n", decryptedText)
    fileopt.PutContents("output.txt", string(ciphertext))

    oDataList := []string{
        `IBAig/wzGocoG1odyF9aRqqwp4UtD4I9SydgaRV3l1MOWYLmrWdtotr+W+rVVKgXv1f/8XU+YdOKq4Hppqu2Imf/pMFPmuAZUfG+Rrwg9sf87JR70lHEx4uG9hXldubb+uL8pU/+ogoE8E78cBCpFuEE0gFUqgMkX0sttKwOs3McCfiE6ni49GMYEW3pReBPQ78C50H2Lgo1j8Uh77M6EZoHj1Dn8Mu7youZZAAXTH+8o7l5csFLqlTUULXMgOuBc9N6jJ9na7MhYaz7freK18l7na1ATDFZc3gITaThehW4rFNpPr9IvKuBw+NDirgn0Olq9H/mPm3fHfxAhLCQxw==`,
        `rQevqTepeouWxRDy7QyoRLOCguQk3ZGWLUW5T/IELQfIRJk80CxFC0Bs9Fq+wGFVg+qjF6k5LLi4RMk0gYfj7WHoZHzFb2Z3x3JFZ1h3c/w9Aig/bOkozOi7qWqDUdPcX5sna8tm9p3VhdFsTsdfZBbaqkRIUPO5HgJfXEnNYMwUze1COpclm3EHAMBlo8gSpS7znFEQmvhnjIq52PG180/rSljdLSTsMs7Co+HKcrRW9cowQt4fl19x4SDcDVVrOGEM1Rv7itf0Zo5GSMJnQ16MWGG1T3sIsJ6IsaZey7xF3Xew33vYm+cqjM1o5omZa0buu4iSkBZIeSfSHxLRFg==`,
        `fXSS3j5Lcb1PkIoClfPRCscmBIkbQ6LAKUIcs7a3fubWodmCmN/ZT8NEVheo7D4DcIo97ATQhxlcJeZzIqJRRY+9PoEp2FRP7sXOf1OmC4YHrYuPCd+XnY1XEEYERFQlUNNgckhGPkq3p832SV4RnZDvNcJspa8suk+ZpAu8P03mn9R49QOmQH65ldqG+11coqxFOgH08qjeE6IfJHjFtXrbGQ7UzTOQg7PwEOj6VbJ2BG3Vobh80XqWNab5iquqsaNsWu0mXujzdagUbnG8PXvsUk+LFh7Zw0XVe1y07zhB9qMrvVkYdeTe556jTMQ6lkzU+X6aiQ9DBtDETa9weA==`,
    }

    for _, oData := range oDataList {

        decryptedText, err = base64DecodeAndDecrypt(loadedPriv, oData)
        if err != nil {
            panic(err)
        }
        fmt.Println("oData: ", oData)
        fmt.Printf("Decrypted text: %s\n", decryptedText)
    }
}

func encryptAndBase64Encode(pub *rsa.PublicKey, plaintext []byte) (string, error) {
    ciphertext, err := rsa.EncryptPKCS1v15(rand.Reader, pub, plaintext)
    if err != nil {
        return "", err
    }
    // Base64编码
    encodedCiphertext := base64.StdEncoding.EncodeToString(ciphertext)
    return encodedCiphertext, nil
}

func base64DecodeAndDecrypt(priv *rsa.PrivateKey, encodedCiphertext string) ([]byte, error) {
    // Base64解码
    ciphertext, err := base64.StdEncoding.DecodeString(encodedCiphertext)
    if err != nil {
        return nil, err
    }
    // 解密
    decryptedText, err := rsa.DecryptPKCS1v15(rand.Reader, priv, ciphertext)
    if err != nil {
        return nil, err
    }
    return decryptedText, nil
}

func generateKeyPair(bits int) (*rsa.PrivateKey, error) {
    privateKey, err := rsa.GenerateKey(rand.Reader, bits)
    if err != nil {
        return nil, err
    }
    return privateKey, nil
}

func savePrivateKey(privateKey *rsa.PrivateKey, filename string) error {
    outFile, err := os.Create(filename)
    if err != nil {
        return err
    }
    defer outFile.Close()

    var privateKeyBytes = x509.MarshalPKCS1PrivateKey(privateKey)
    pem.Encode(outFile, &pem.Block{
        Type:  "RSA PRIVATE KEY",
        Bytes: privateKeyBytes,
    })
    return nil
}

func savePublicKey(publicKey rsa.PublicKey, filename string) error {
    asn1Bytes, err := x509.MarshalPKIXPublicKey(&publicKey)
    if err != nil {
        return err
    }

    outFile, err := os.Create(filename)
    if err != nil {
        return err
    }
    defer outFile.Close()

    pem.Encode(outFile, &pem.Block{
        Type:  "RSA PUBLIC KEY",
        Bytes: asn1Bytes,
    })
    return nil
}

func loadPrivateKey(filename string) (*rsa.PrivateKey, error) {
    inFile, err := os.Open(filename)
    if err != nil {
        return nil, err
    }
    defer inFile.Close()

    var privKey *rsa.PrivateKey
    pemData, err := io.ReadAll(inFile)
    if err != nil {
        return nil, err
    }

    block, _ := pem.Decode(pemData)
    if block == nil {
        return nil, fmt.Errorf("failed to parse PEM block containing the key")
    }

    privKey, err = x509.ParsePKCS1PrivateKey(block.Bytes)
    if err != nil {
        return nil, err
    }

    return privKey, nil
}

func loadPublicKey(filename string) (*rsa.PublicKey, error) {
    inFile, err := os.Open(filename)
    if err != nil {
        return nil, err
    }
    defer inFile.Close()

    pemData, err := io.ReadAll(inFile)
    if err != nil {
        return nil, err
    }

    block, _ := pem.Decode(pemData)
    if block == nil {
        return nil, fmt.Errorf("failed to parse PEM block containing the key")
    }

    pub, err := x509.ParsePKIXPublicKey(block.Bytes)
    if err != nil {
        return nil, err
    }

    switch pub := pub.(type) {
    case *rsa.PublicKey:
        return pub, nil
    default:
        return nil, fmt.Errorf("public key is not RSA")
    }
}

func encrypt(pub *rsa.PublicKey, plaintext []byte) ([]byte, error) {
    return rsa.EncryptPKCS1v15(rand.Reader, pub, plaintext)
}

func decrypt(priv *rsa.PrivateKey, ciphertext []byte) ([]byte, error) {
    return rsa.DecryptPKCS1v15(rand.Reader, priv, ciphertext)
}

本作品采用《CC 协议》,转载必须注明作者和本文链接
《L05 电商实战》
从零开发一个电商项目,功能包括电商后台、商品 & SKU 管理、购物车、订单管理、支付宝支付、微信支付、订单退款流程、优惠券等
《G01 Go 实战入门》
从零开始带你一步步开发一个 Go 博客项目,让你在最短的时间内学会使用 Go 进行编码。项目结构很大程度上参考了 Laravel。
讨论数量: 6

纯代码就不存在安全的可能,不存在不被逆向的代码

5个月前 评论
我们只希望世界和平 (楼主) 5个月前
我们只希望世界和平 (楼主) 5个月前

这。好无聊的帖子

4个月前 评论

我理解就是无法加密,任何方式前端代码都暴露出来了,只要有心人想破解都可以破解。 但是可以增加解密难度,可以用简单的密钥计算出密钥每次都传给后端验签,后端验签以及密钥过期时间。 首先你前端有混淆代码,这样大部分人觉得麻烦恶心就懒得去整你的接口了。

4个月前 评论

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!
文章
51
粉丝
16
喜欢
57
收藏
43
排名:519
访问:1.6 万
私信
所有博文
社区赞助商