110,825
社区成员
![](https://csdnimg.cn/release/cmsfe/public/img/topic.427195d5.png)
![](https://csdnimg.cn/release/cmsfe/public/img/me.40a70ab0.png)
![](https://csdnimg.cn/release/cmsfe/public/img/task.87b52881.png)
![](https://csdnimg.cn/release/cmsfe/public/img/share-circle.3e0b7822.png)
有一段java版本的demo,是完全没有问题的.验证可以通过.
public static String sign(String input, String encodedPrivateKey) throws Exception {
Signature signature = getInstance();
signature.initSign(privateKey(encodedPrivateKey));
signature.update(input.getBytes(StandardCharsets.UTF_8));
return new String(Base64.getEncoder().encode(signature.sign()), StandardCharsets.UTF_8);
}
private static PrivateKey privateKey(String encodedPrivateKey) throws Exception {
return KeyFactory.getInstance(EC, new BouncyCastleProvider()).generatePrivate(new PKCS8EncodedKeySpec(Base64.getDecoder().decode(encodedPrivateKey)));
}
public static boolean verify(String input, String encodedPublicKey, String sign) throws Exception {
final Signature signature = getInstance();
signature.initVerify(publicKey(encodedPublicKey));
signature.update(input.getBytes(StandardCharsets.UTF_8));
return signature.verify(Base64.getDecoder().decode(sign));
}
我在C#中,写了一个.可以正常加签,但是加签后验证无法通过.
private void btnSign_Click(object sender, EventArgs e)
{
//TxCode + 时间 + 应用id
String yyyyMMdd = DateTime.Now.ToString("yyyyMMdd");
String siginBefore = "FCSP" + yyyyMMdd + certificate;
// 获取sessionKey
String sessionKeyWithSm4WithBase64 = generateSignKey();
txtSinger.Text = sessionKeyWithSm4WithBase64;
}
public static AsymmetricKeyParameter PrivateASYKeyFromBase64(string encodedPrivateKey)
{
byte[] privateKeyBytes = Convert.FromBase64String(encodedPrivateKey);
// 假设私钥是以PKCS#8格式编码的
AsymmetricKeyParameter keyParam = PrivateKeyFactory.CreateKey(privateKeyBytes);
// 检查私钥是否为椭圆曲线私钥
if (!(keyParam is ECPrivateKeyParameters ecPrivateKey))
{
throw new ArgumentException("The provided private key is not an EC private key.", nameof(encodedPrivateKey));
}
return keyParam;
}
//签名
private string generateSignKey()
{
try
{
//AsymmetricKeyParameter bcecPrivateKey = PrivateASYKeyFromBase64(privateKey);
byte[] msg = System.Text.Encoding.UTF8.GetBytes(siginBefore);
byte[] sig = GmUtil.SignSm3WithSm2(msg,null, PrivateASYKeyFromBase64(privateKey));
//return Convert.ToBase64String(sig); //这样不行.
string utf8String = System.Text.Encoding.UTF8.GetString(sig);
byte[] bytes = System.Text.Encoding.UTF8.GetBytes(utf8String);
string base64String = Convert.ToBase64String(bytes);
return base64String; //这样也不行.
}
catch (Exception ex)
{
return "error" + ex.Message;
}
}
/**
* 签名
* @param msg
* @param userId
* @param privateKey
* @return r||s,直接拼接byte数组的rs
*/
public static byte[] SignSm3WithSm2(byte[] msg, byte[] userId, AsymmetricKeyParameter privateKey)
{
return RsAsn1ToPlainByteArray(SignSm3WithSm2Asn1Rs(msg, userId, privateKey));
}
/**
* @param msg
* @param userId
* @param privateKey
* @return rs in <b>asn1 format</b>
*/
public static byte[] SignSm3WithSm2Asn1Rs(byte[] msg, byte[] userId, AsymmetricKeyParameter privateKey)
{
try
{
ISigner signer = SignerUtilities.GetSigner("SM3withSM2");
//signer.Init(true, new ParametersWithID(privateKey, userId));
ICipherParameters cp = new ParametersWithRandom(privateKey);
signer.Init(true, cp);
signer.BlockUpdate(msg, 0, msg.Length);
byte[] sig = signer.GenerateSignature();
return sig;
}
catch (Exception e)
{
//log.Error("SignSm3WithSm2Asn1Rs error: " + e.Message, e);
return null;
}
}
/**
* BC的SM3withSM2签名得到的结果的rs是asn1格式的,这个方法转化成直接拼接r||s
* @param rsDer rs in asn1 format
* @return sign result in plain byte array
*/
private static byte[] RsAsn1ToPlainByteArray(byte[] rsDer)
{
Asn1Sequence seq = Asn1Sequence.GetInstance(rsDer);
byte[] r = BigIntToFixexLengthBytes(DerInteger.GetInstance(seq[0]).Value);
byte[] s = BigIntToFixexLengthBytes(DerInteger.GetInstance(seq[1]).Value);
byte[] result = new byte[RS_LEN * 2];
Buffer.BlockCopy(r, 0, result, 0, r.Length);
Buffer.BlockCopy(s, 0, result, RS_LEN, s.Length);
return result;
}
请大神帮忙给看看.