Ruby 国密 SM2,Ruby 怎么实现?

zqalyc · 2022年10月18日 · 最后由 zqalyc 回复于 2022年10月27日 · 1195 次阅读

请问国密 SM2(加密模式 C1C3C2)有没有 ruby 的加解密?

Ruby 中的 OpenSSL 可以使用 SM2 算法,openssl 需要 >= 1.1.1k

require 'openssl'
OpenSSL::PKey::EC.new("SM2")
sapeu 回复

能再详细介绍下使用例子么 谢谢 🤔

zqalyc 回复

源码有讲解

源码加密理解:

key = OpenSSL::PKey::EC.new("SM2")
key.generate_key
public_key = key.public_key

public_key_hex = public_key.to_bn.to_s(16).downcase

# 加密
data = "123"
signature = key.dsa_sign_asn1(data)
signature_base64 = Base64.encode64(signature).gsub("\n", "")

如果前提已知 公钥和秘钥了,使用 group 方式重新赋值公钥秘钥加密,和 java 加密不一致,java 不能解密,求解?

public_key = "041b0aebadc6444cce91d0c17add879cee687c12a0e6c6373f63dfb5d8253261829c909743567878b037f173980c8a7d744eb54fcb47fa2f585e18fd3619eee988"
private_key = "f3898159803d4ba4484232d9e29acdda1d098ffc37a5d64db96b606794b43572"
data = "123" # 待加密数据

group = OpenSSL::PKey::EC::Group.new('SM2')
ec = OpenSSL::PKey::EC.new(group)
ec.private_key = OpenSSL::BN.new(private_key, 16)
public_key_bn = OpenSSL::BN.new(public_key, 16)
point = OpenSSL::PKey::EC::Point.new(group, public_key_bn)
ec.public_key = point
signature = ec.dsa_sign_asn1(data)
signature_base64 = Base64.encode64(signature).gsub("\n", "")

找了几天,没找到 SM2 的加解密😂 ,只找到了签名和验签😅

但是吧,可以换个思路呀,既然你 JAVA 实现了,你可以用 JAVA 生成个 jar 包,然后用 Ruby 执行对应 jar 包命令

sapeu 回复

好的 多谢😀 那就用 java 写个吧

java 的代码和结果发上来看看

sevk 回复

java 加密代码示例

// 公钥测试数据
String encodedPub = "041b0aebadc6444cce91d0c17add879cee687c12a0e6c6373f63dfb5d8253261829c909743567878b037f173980c8a7d744eb54fcb47fa2f585e18fd3619eee988";
// 待加密数据
String data = "123"; 
final String SPEC_NAME = "sm2p256v1";
final X9ECParameters x9ECParameters = GMNamedCurves.getByName(SPEC_NAME);
final ECDomainParameters ecDomainParameters = new ECDomainParameters(x9ECParameters.getCurve(), x9ECParameters.getG(), x9ECParameters.getN());
byte[] pointBytes = Hex.decode(encodedPub);
ECPoint q = x9ECParameters.getCurve().decodePoint(pointBytes);
ECPublicKeyParameters ecPublicKeyParameters = new ECPublicKeyParameters(q, ecDomainParameters);
// 采用 C1 || C3 || C2 的模式
SM2Engine sm2Engine = new SM2Engine(SM2Engine.Mode.C1C3C2);
sm2Engine.init(true, new ParametersWithRandom(ecPublicKeyParameters));
byte[] dataBytes = data.getBytes();
byte[] cipherBytes = sm2Engine.processBlock(dataBytes, 0, dataBytes.length);
//加密结果
String encryptedData = new String(Base64.encode(cipherBytes));

加密结果

BLTZm74dfgY+11nF3uXPP383l7su5gBUb+tZJSWuBeeYoODuDUC+cgPfIxNdWsaNwjmis1Inca0NR32phYWynP/3HnFX3VJ0LFZYhUDdwuAApO72o23D5bWPiaR7Pkb3+/n7PA==
需要 登录 后方可回复, 如果你还没有账号请 注册新账号