Gem 用纯 Ruby 实现了国密 SM2 密码算法

numbcoder · May 10, 2023 · Last by 2480885238 replied at December 05, 2023 · 1486 hits

OpenSSL 自 1.1.1 之后,已经加入了国密标准 SM2/SM3/SM4 算法实现,但是 Ruby 标准库中对 OpenSSL 只是做了一个通用的封装,很多特殊的算法调用需要自己去封装 C API。比如 SM2 就是基于 ECC(椭圆加密算法)的非对称加密算法,同时还能数字签名,Ruby 并没有封装 SM2 的具体 API,好在已经封装了 OpenSSL 中 ECC 和 BigNumber 相关的操作,实现起来比别的语言要省心很多。

Github 地址:https://github.com/numbcoder/sm2-crypto

算法实现基于国家密码管理局发布的 SM2 椭圆曲线公钥密码算法,详细用法可以参照 Readme 和测试用例

基本用法:

require 'sm2_crypto'

# 生成密钥对
keypair = OpenSSL::PKey::EC.generate("SM2")
private_key = keypair.private_key.to_s(2)
public_key = keypair.public_key.to_octet_string(:uncompressed)

# 加密
message = "Hello, SM2 encryption!"
encrypted_data = SM2Crypto.encrypt(public_key, message)
# 解密
decrypted_message = SM2Crypto.decrypt(private_key, encrypted_data)

# 签名
sign = SM2Crypto.sign(private_key, message)
# 验签
SM2Crypto.verify(public_key, message, sign)

SM3/SM4 是通用实现,可以直接调用,无需自己封装

# SM3 摘要算法:
OpenSSL::Digest.new("sm3", "abc").to_s
# => "66c7f0f462eeedd9d1f2d46bdc10e4e24167c4875cf2f7a2297da02b8f4ba8e0"

SM4 对称加解密

def sm4_decrypt(key, data)
  decipher = OpenSSL::Cipher.new("sm4-ecb")
  decipher.decrypt
  decipher.key = key

  decipher.update(data) + decipher.final
end

def sm4_encrypt(key, data)
  cipher = OpenSSL::Cipher.new("sm4-ecb")
  cipher.encrypt
  cipher.key = key

  cipher.update(data) + cipher.final
end

感谢,最近正好要对接腾讯云的 E 证通,需要国密 2 的加解密。

试一试试一试

很好啊👍 之前 ruby 用 SM2,还要用 java 实现

decipher.final 这个为什么一直提示 wrong final block length

Reply to 13520628201

sm4 吗?大概率是你的 key 格式不对,要传二进制字符串进去

Rei in 求 Ruby 的签名算法----国密 Sm3WithSm2 mention this topic. 29 Jul 17:24

您好,请问一下。系统中引入了 OpenSSL 库,可以调用 aes 算法,但是调用 sm4 的时候显示不支持该算法,调用方式是和您这个一致的,unsupported cipher algorithm (sm4-ecb)

OpenSSL 1.1.1h 22 Sep 2020 是不是版本低了的问题

You need to Sign in before reply, if you don't have an account, please Sign up first.