跨语言加解密总对不上?这个纯 Go 神库让 AES/RSA 与 PHP、Java 100% 互通

在 Go 语言中,密码学开发一直是一部"双城记"。

一方面,Go 标准库的 crypto/* 包设计精良、安全且高效。但另一方面,实现日常的加解密工作流------比如用 AES-CBC(PKCS#7)加密 Payload、针对老旧系统执行 AES-ECB,或是对超大 Payload 进行 RSA 加密------需要编写数十行重复且繁琐的样板代码。

更糟糕的是,填充方案(Padding)、IV 向量处理或密钥截断上的细微差异,在与 PHP(openssl_encrypt)、Java(javax.crypto)、Python(pycryptodome)或 Node.js 通信时,往往会导致令人抓狂的跨语言解密失败。

为了彻底解决这些痛点,欢迎使用 go-think/openssl ------ 一个对开发者友好、纯 Go 实现的密码学工具包,为 Go 应用带来了极简体验与无缝的跨平台互操作性。

💡 为什么选择 go-think/openssl?

  • 纯 Go 实现,无 CGO 依赖:轻量级、跨平台交叉编译友好,完全构建在 Go 标准密码学原语之上。
  • 零样板代码 API:将原本需要 40 行代码才能完成的操作缩减至 2 到 3 行。
  • 100% 跨语言兼容:生成与 OpenSSL、PHP、Java、Python 及 Node.js 在二进制层面完全一致的密文。
  • 智能填充与自动分块
    • 原生支持 PKCS#7(PKCS#5)与 ZeroPadding。
    • 对任意长度消息的 RSA 加密和解密提供自动分块支持。
  • 功能齐全(Batteries Included):内置 AES、DES、3DES、RSA、MD5、SHA-1 至 SHA-512 以及 HMAC。

🚀 快速安装

bash 复制代码
go get -u github.com/go-think/openssl

🛠️ 代码实战

1. 对称加密:AES(CBC、ECB 与 GCM)

标准 Go 库需要手动处理数据块填充、块模式初始化以及切片操作。在 go-think/openssl 中,一切变得极度简单:

AES-CBC 与 PKCS#7 填充

go 复制代码
package main

import (
	"encoding/base64"
	"fmt"

	"github.com/go-think/openssl"
)

func main() {
	src := []byte("Hello, Cross-Language World!")
	key := []byte("1234567890123456") // AES-128 16 字节密钥
	iv := []byte("1234567890123456")  // 16 字节 IV

	// 加密
	cipherText, err := openssl.AesCBCEncrypt(src, key, iv, openssl.PKCS7_PADDING)
	if err != nil {
		panic(err)
	}
	fmt.Println("Base64 Ciphertext:", base64.StdEncoding.EncodeToString(cipherText))

	// 解密
	plainText, err := openssl.AesCBCDecrypt(cipherText, key, iv, openssl.PKCS7_PADDING)
	if err != nil {
		panic(err)
	}
	fmt.Println("Decrypted:", string(plainText))
}

现代 AEAD:AES-GCM(认证加密)

对于需要完整性校验与防篡改认证的应用场景:

go 复制代码
nonce := []byte("123456789012")          // 12 字节标准 Nonce
aad := []byte("authenticated_header")    // 附加认证数据

// 加密
dst, err := openssl.AesGCMEncrypt(src, key, nonce, aad)

// 解密
plain, err := openssl.AesGCMDecrypt(dst, key, nonce, aad)

此外,还开箱即用支持 CFB、OFB、CTR 模式,以及老旧系统常用的 DES 和 3DES 算法。

2. 无痛 RSA:密钥生成、签名与自动分块

原生 RSA 的一大痛点在于无法加密超过其密钥模长扣除填充后上限的数据。通常开发者必须自行编写分块与缓冲区拼接逻辑。go-think/openssl 在底层自动处理了这一切:

go 复制代码
package main

import (
	"bytes"
	"crypto"
	"fmt"

	"github.com/go-think/openssl"
)

func main() {
	// 1. 生成 2048 位 PEM 格式 RSA 密钥对
	var privBuf, pubBuf bytes.Buffer
	_ = openssl.RSAGenerateKey(2048, &privBuf)
	_ = openssl.RSAGeneratePublicKey(privBuf.Bytes(), &pubBuf)
	privKey := privBuf.Bytes()
	pubKey := pubBuf.Bytes()

	// 2. 加密任意长度数据(底层自动分块)
	longData := []byte("A very long message that exceeds standard RSA block size limit...")
	encrypted, _ := openssl.RSAEncrypt(longData, pubKey)

	// 解密
	decrypted, _ := openssl.RSADecrypt(encrypted, privKey)
	fmt.Println("Decrypted RSA:", string(decrypted))

	// 3. 数字签名(RSASign 与 RSAVerify)
	signature, _ := openssl.RSASign(longData, privKey, crypto.SHA256)
	err := openssl.RSAVerify(longData, signature, pubKey, crypto.SHA256)
	if err == nil {
		fmt.Println("Signature verified successfully!")
	}
}

注意:RSAEncrypt 同时也无缝支持 X.509 CERTIFICATE PEM 证书块!

3. 一行搞定 Hash 与 HMAC

无需再为提取一个十六进制哈希值去创建 hash.Hash 接口:

go 复制代码
// MD5
hexMD5 := openssl.Md5ToString("hello world")

// SHA-256
hexSHA := openssl.Sha256ToString("hello world")

// HMAC-SHA256
hmacStr := openssl.HmacSha256ToString("secret-key", "hello world")

🌐 100% 跨语言互操作性:Go vs. PHP vs. Java

测试验证 Go 生成的密文是否与其他平台逐位(bit-for-bit)一致。

在 Go 中(go-think/openssl):

go 复制代码
src := []byte("123456")
key := []byte("1234567890123456")
iv := []byte("1234567890123456")
dst, _ := openssl.AesCBCEncrypt(src, key, iv, openssl.PKCS7_PADDING)
fmt.Println(base64.StdEncoding.EncodeToString(dst)) // 输出: 1jdzWuniG6UMtoa3T6uNLA==

在 PHP 中(openssl_encrypt):

php 复制代码
<?php
$data = "123456";
$key = "1234567890123456";
$iv = "1234567890123456";
$encrypted = openssl_encrypt($data, 'aes-128-cbc', $key, OPENSSL_RAW_DATA, $iv);
echo base64_encode($encrypted); // 输出: 1jdzWuniG6UMtoa3T6uNLA== (完全一致!)

在 Java 中(javax.crypto):

java 复制代码
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
cipher.init(Cipher.ENCRYPT_MODE, new SecretKeySpec(key.getBytes(), "AES"), new IvParameterSpec(iv.getBytes()));
byte[] encrypted = cipher.doFinal(data.getBytes(StandardCharsets.UTF_8));
System.out.println(Base64.getEncoder().encodeToString(encrypted)); // 输出: 1jdzWuniG6UMtoa3T6uNLA== (完全一致!)

📦 总结

如果你正在构建需要与外部 API、遗留系统、移动端应用或其他后端交互的 Go 微服务,而不想再为加解密差异头疼,go-think/openssl 将为你节省数小时的调试时间。

如果觉得对你有帮助,欢迎在 GitHub 上给它点个 ⭐ Star,也欢迎提交 Issue 或 Pull Request!

原文:跨语言加解密总对不上?这个纯 Go 神库让 AES/RSA 与 PHP、Java 100% 互通

相关推荐
LINgZone21 小时前
系统架构与分支规范
java·数据库·架构
用户594404103561 小时前
从零手写轻量级 RPC 框架:基于 Netty + Zookeeper 的核心实现
后端
AC赳赳老秦1 小时前
企业级合规审计体系:用 OpenClaw 落地采集全链路留痕,自动生成合规审计报告
java·python·django·beautifulsoup·php·deepseek·openclaw
FEF前端团队2 小时前
小程序微信支付 V3 接入实战手册:从商户配置到前后端落地
javascript·后端·node.js
吃杠碰小鸡2 小时前
VsCode中开发Java项目
java·vscode
宠友信息2 小时前
内容社区源码开发实践解析,用Spring Boot打造1:1仿小红书源码平台
java·spring boot·redis·websocket·mysql·spring·uni-app
马可家的菠萝2 小时前
自动保存已经有了,为什么笔记软件还需要“历史版本”?
前端·后端·架构
leavesleo2 小时前
AI Agent 开发实战:从零搭一个能用的 Agent
后端