嘻嘻龙呵呵炉子 2023-08-10 17:45 采纳率: 0%
浏览 19
已结题

c#和python互相签名验签

我在c#上和python上面各搭了一套RSA签名验签的系统,但是在c#上和python上的验签互相不能通过(c#签名python验签,python签名c#验签),只能在c#或者python自己的环境下,自己验签自己通过(就是c#签名 c#验签,python签名 python验签)。

请问为什么不能互通,帮忙看看问题在哪。
条件:c#签名helloworld python验签通过,PSS填充 SHA256 ,mgf=padding.MGF1(hashes.SHA256()), (盐度应该为32字节,但是c#里面没得选不知道为啥) 加密方法就是python里的配置。
最好还能和 https://try8.cn/tool/cipher/rsa 这个网站上的也互通,能弄好可以追加悬赏都可以。

以下是我的c#代码

using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Cryptography;
using System.Text;
using System.IO;


static void Main(string[] args)
{
RSANissan RSAInstance = new RSANissan();

RSAInstance.PublicKey = "‘’‘’";
RSAInstance.PrivateKey = "‘’‘’";


if (true)
            {
                byte[] DataToSign = new byte[] { 1 };

                byte[] SignData = RSAInstance.RSAHashSign(DataToSign, HashAlgorithmName.SHA256, RSASignaturePadding.Pss);
                string[] hexStrings = SignData.Select(b => b.ToString("X2")).ToArray();
                Console.WriteLine(string.Join(" ", hexStrings));

                string VerifyResult = RSAInstance.RSAHashVerify(DataToSign, SignData, HashAlgorithmName.SHA256, RSASignaturePadding.Pss);

                Console.WriteLine($"result = {VerifyResult}");

                /*****************************************字符串签名*****************************************/

                String DataToSignStr = "Hello World!";

                SignData = RSAInstance.RSAHashSign(DataToSignStr, HashAlgorithmName.SHA256, RSASignaturePadding.Pss);
                VerifyResult = RSAInstance.RSAHashVerify(DataToSignStr, SignData, HashAlgorithmName.SHA256, RSASignaturePadding.Pss);

                Console.WriteLine($"result = {VerifyResult}");

                Console.ReadKey();
            }
}

public class RSANissan
    {
          public string PublicKey { get; set; }
          public string PrivateKey { get; set; }

          public byte[] RSAHashSign(string hash, HashAlgorithmName hashAlgorithm, RSASignaturePadding padding)
        {
            RSACng rsa = new RSACng();
            rsa.FromXmlString(PrivateKey);

            byte[] Hash_byteArray = Encoding.UTF8.GetBytes(hash);

            byte[] SignData = rsa.SignHash(Hash_byteArray, hashAlgorithm, padding);

            return SignData;
        }

        public string RSAHashVerify(byte[] hash, byte[] signature, HashAlgorithmName hashAlgorithm, RSASignaturePadding padding)
        {
            string result = "fail";

            RSACng rsa = new RSACng();
            rsa.FromXmlString(PrivateKey);
            bool VerifyResult = rsa.VerifyHash(hash, signature, hashAlgorithm, padding);

            if (VerifyResult)
            {
                result = "pass";
            }

            return result;
        }
}

公私钥由于是自己使用的就不提供了,主要用的就是c#官方的rsa模块,用的rsacng类里的签名验签方法,方法网站如下。
https://learn.microsoft.com/zh-cn/dotnet/api/system.security.cryptography.rsa.verifydata?view=net-7.0

以下是我的python代码

from cryptography.hazmat.primitives import hashes
from cryptography.hazmat.primitives.asymmetric import padding
from cryptography.hazmat.primitives.serialization import (
    load_pem_private_key,
    load_pem_public_key
)
import binascii
import base64

def verify_signature(public_key_path, signature, data):
    with open(public_key_path, 'rb') as key_file:
        public_key = load_pem_public_key(key_file.read())

    try:
        public_key.verify(
            signature,
            data.encode('utf-8'),
            padding.PSS(
                mgf=padding.MGF1(hashes.SHA256()),
                salt_length=32,
            ),
            hashes.SHA256()
        )
        return True
    except :
        return False
    

# 输入参数
public_key_path = r'‘’‘'
data = 'helloworld'
print(type(data.encode('utf-8')))
print(data.encode('utf-8'))

signature = '6A4E0C09990735DC624F1F8362C750A1952401C603A7A6E1A42CFC25C8A222AF5CE224426CC973E56F7E435E6FD47BBE060A0D73E5643E138F73C47B9C530C27FE735A8C18F44DEDDF5DF14BA723333C73D83F44841C0E430E165D57A43FED7033F62733782ED74D568C599BFA28801B1784A570AF8C317C592A2F68DF97B80BA2F221FC673D11B96C1E637EDF356F6DCB39AA5F3BB60445A2C4319BCB2C76A4BA80BAEE1CDC4E3C07FF9DF0C269521C8BA6FA26503E98C0549B78E2A8471FB4367FBF52BF5E3EB2F1269BA656A38AE61517F54689F144BC6889FFB6EF182533E63642884F2DC28769C079259C39061DE01B7987535DAC7CD8D55A0959C8C7AB'



# 验证签名
is_valid = verify_signature(public_key_path, signature, data)
print("Signature verification result:", is_valid)

主要使用的是cryptography库,密钥也不提供了。

  • 写回答

6条回答 默认 最新

  • 专家-郭老师 Java领域新星创作者 2023-08-10 17:54
    关注

    最简单的办法就是,你用相同的内容,在c#和python 中都加密,然后输出下结果是不是一样的,不是一样就说明其中有一个加密不对。
    而且两边公钥或者私钥要一样

    评论

报告相同问题?

问题事件

  • 已结题 (查看结题原因) 8月14日
  • 赞助了问题酬金50元 8月11日
  • 创建了问题 8月10日

悬赏问题

  • ¥15 陆空双模式无人机飞控设置
  • ¥15 sentaurus lithography
  • ¥100 求抖音ck号 或者提ck教程
  • ¥15 关于#linux#的问题:子进程1等待子进程A、B退出后退出(语言-c语言)
  • ¥20 web页面如何打开Outlook 365的全球离线通讯簿功能
  • ¥15 io.jsonwebtoken.security.Keys
  • ¥15 急,ubuntu安装后no caching mode page found等
  • ¥15 联想交换机NE2580O/NE1064TO安装SONIC
  • ¥15 防火墙的混合模式配置
  • ¥15 Ubuntu不小心注销了要怎么恢复啊