Golang中RSA的X931标准支持探讨
Golang中RSA的X931标准支持探讨 根据 https://golang.org/pkg/crypto/rsa/ 上的文档,目前没有针对 X9.31 方案的函数。RSA 是否有这样的实现?在哪里可以找到它?
1 回复
更多关于Golang中RSA的X931标准支持探讨的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
在标准库 crypto/rsa 中确实没有直接支持 X9.31 标准的函数。不过,可以通过组合现有功能来实现 X9.31 的填充方案。以下是一个示例实现:
package main
import (
"crypto/rand"
"crypto/rsa"
"crypto/sha256"
"errors"
"hash"
"io"
)
// X931Padding 实现 X9.31 填充
func X931Padding(msg []byte, n int, hash hash.Hash, random io.Reader) ([]byte, error) {
hashLen := hash.Size()
if len(msg) > n-2*hashLen-2 {
return nil, errors.New("message too long")
}
// 步骤1: 计算哈希
hash.Write(msg)
H := hash.Sum(nil)
hash.Reset()
// 步骤2: 生成随机数
R := make([]byte, hashLen)
if _, err := io.ReadFull(random, R); err != nil {
return nil, err
}
// 步骤3: 构造填充块
padding := make([]byte, n)
padding[0] = 0x6B
pos := 1
// 插入哈希 H
copy(padding[pos:], H)
pos += hashLen
// 插入 PS (填充字符串)
psLen := n - len(msg) - 2*hashLen - 2
for i := 0; i < psLen; i++ {
padding[pos] = 0xBB
pos++
}
padding[pos] = 0xBA
pos++
// 插入随机数 R
copy(padding[pos:], R)
pos += hashLen
// 插入消息
copy(padding[pos:], msg)
pos += len(msg)
padding[n-1] = 0xCC
return padding, nil
}
// X931Unpadding 实现 X9.31 去填充
func X931Unpadding(padded []byte, hash hash.Hash) ([]byte, error) {
n := len(padded)
hashLen := hash.Size()
if n < 2*hashLen+2 {
return nil, errors.New("invalid padding length")
}
if padded[0] != 0x6B || padded[n-1] != 0xCC {
return nil, errors.New("invalid padding markers")
}
// 提取哈希 H
H := padded[1 : 1+hashLen]
// 查找分隔符 0xBA
baIndex := -1
for i := 1 + hashLen; i < n-hashLen-1; i++ {
if padded[i] == 0xBA {
baIndex = i
break
}
}
if baIndex == -1 {
return nil, errors.New("separator not found")
}
// 提取随机数 R
R := padded[baIndex+1 : baIndex+1+hashLen]
// 提取消息
msg := padded[baIndex+1+hashLen : n-1]
// 验证哈希
hash.Write(msg)
computedH := hash.Sum(nil)
hash.Reset()
if !equal(H, computedH) {
return nil, errors.New("hash verification failed")
}
// 这里可以添加对随机数 R 的验证(如果需要)
_ = R
return msg, nil
}
func equal(a, b []byte) bool {
if len(a) != len(b) {
return false
}
for i := range a {
if a[i] != b[i] {
return false
}
}
return true
}
// 使用示例
func main() {
// 生成 RSA 密钥
privKey, err := rsa.GenerateKey(rand.Reader, 2048)
if err != nil {
panic(err)
}
// 原始消息
message := []byte("Hello X9.31")
// X9.31 填充
hash := sha256.New()
padded, err := X931Padding(message, privKey.PublicKey.Size(), hash, rand.Reader)
if err != nil {
panic(err)
}
// RSA 加密
encrypted, err := rsa.EncryptPKCS1v15(rand.Reader, &privKey.PublicKey, padded)
if err != nil {
panic(err)
}
// RSA 解密
decrypted, err := rsa.DecryptPKCS1v15(rand.Reader, privKey, encrypted)
if err != nil {
panic(err)
}
// X9.31 去填充
hash.Reset()
original, err := X931Unpadding(decrypted, hash)
if err != nil {
panic(err)
}
println("Decrypted message:", string(original))
}
这个实现包含了 X9.31 的主要步骤:
- 计算消息哈希
- 生成随机数
- 构造填充块
- 验证机制
如果需要完整的 X9.31 标准实现,可以考虑以下第三方库:
github.com/enceve/crypto/x931github.com/tjfoc/gmsm/sm2(包含相关实现)
注意:生产环境使用时需要更严格的错误处理和边界检查。

