请问国密 SM2(加密模式 C1C3C2)有没有 ruby 的加解密?
Ruby 中的 OpenSSL 可以使用 SM2 算法,openssl
需要 >= 1.1.1k
require 'openssl'
OpenSSL::PKey::EC.new("SM2")
源码加密理解:
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 包命令
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==