使用ASP.NET和Bouncy Castle的CRYSTALS-DILITHIUM数字签名

eqoofvh9  于 2023-04-22  发布在  .NET
关注(0)|答案(1)|浏览(176)

我正在用ASP.NET写一个点对点文件共享系统。客户端需要能够验证他们的文件来自一个值得信任的作者。客户端拥有他们信任的作者的公钥,作者应该对他们共享的文件进行数字签名。
我想使用CRYSTALS-DILITHIUM来生成和验证这些签名,并使用Bouncy Castle's .NET library v2.2.0来实现算法。
我如何:
1.生成新密钥对
1.使用私钥对消息签名
1.使用公钥验证消息
以下是我目前为止的示例代码:
请注意,有些项目(如new DilithiumPrivateKeyParameters(...)的参数)丢失了,因为我不知道应该在那里放什么。

public static void Generate ()
{
    DilithiumKeyPairGenerator generator = new DilithiumKeyPairGenerator();
    generator.Init(new DilithiumKeyGenerationParameters(
        new SecureRandom(),
        DilithiumParameters.Dilithium5Aes
        ));

    AsymmetricCipherKeyPair keyPair = generator.GenerateKeyPair();

    // All the later methods need bytes of these key - how do I get them?
    AsymmetricKeyParameter publicKey = keyPair.Public;
    AsymmetricKeyParameter privateKey = keyPair.Private;
}

public static void Sign ()
{
    DilithiumSigner signer = new DilithiumSigner();

    // What do I put in all these parameters?
    signer.Init(true, new DilithiumPrivateKeyParameters(
        DilithiumParameters.Dilithium5Aes,
                // byte[] rho,
                // byte[] K,
                // byte[] tr,
                // byte[] s1,
                // byte[] s2,
                // byte[] t1,
                // byte[] t2,
        ));

    string messageText = "Important Message!";

    // Send the message and signature
    byte[] message = Encoding.UTF8.GetBytes(messageText);
    byte[] signature = signer.GenerateSignature(message);
}

public void Verify (byte[] publicKey, byte[] message, byte[] signature)
{
    DilithiumSigner verifier = new DilithiumSigner();

    // The constructor asks for "pkEncoded" - how should the bytes be encoded?
    verifier.Init(false, new DilithiumPublicKeyParameters(publicKey));

    bool good = verifier.VerifySignature(message, signature);
}
2admgd59

2admgd591#

下面是一个签名和验证的工作示例--没有什么是一点类型转换不能解决的!
我发现有用的链接:

  1. Bouncy Castle Sign and Verify SHA256 Certificate With C#
  2. How to generate Private key from string using BouncyCastle
  3. Bouncy Castle C# - getting public key object from byte array
  4. https://github.com/CryptoKass/dilithium/blob/master/src/main/java/org/dilithium/Start.java
  5. https://github.com/rodbate/bouncycastle-examples/blob/master/src/main/java/chapter2/KeyGeneratorExample.java
  6. https://github.com/bcgit/bc-csharp/blob/master/crypto/src/pqc/crypto/crystals/kyber/KyberEngine.cs
    我需要将键维护为Dilithium...KeyParameters,而不是byte[] s或ICypherKeyParameters。这使我可以访问正确的Rho, K, etc.属性和GetEncoded()方法。
public static void Test ()
{
    AsymmetricCipherKeyPair keyPair1 = Generate();
    AsymmetricCipherKeyPair keyPair2 = Generate();

    byte[] message = Encoding.UTF8.GetBytes("Important Message!");
    byte[] signature = Sign((DilithiumPrivateKeyParameters) keyPair1.Private, message);

    // Returns TRUE
    bool check1 = Verify((DilithiumPublicKeyParameters) keyPair1.Public, message, signature);
    // Returns FALSE (as expected)
    bool check2 = Verify((DilithiumPublicKeyParameters) keyPair2.Public, message, signature);
}

public static AsymmetricCipherKeyPair Generate ()
{
    DilithiumKeyPairGenerator generator = new DilithiumKeyPairGenerator();
    generator.Init(new DilithiumKeyGenerationParameters(
        new SecureRandom(),
        DilithiumParameters.Dilithium5Aes
        ));

    AsymmetricCipherKeyPair keyPair = generator.GenerateKeyPair();

    return keyPair;
}

public static byte[] Sign (DilithiumPrivateKeyParameters privateKey, byte[] message)
{
    DilithiumSigner signer = new DilithiumSigner();

    // What do I put in all these parameters?
    signer.Init(true, new DilithiumPrivateKeyParameters(
        DilithiumParameters.Dilithium5Aes,
                privateKey.Rho,
                privateKey.K,
                privateKey.Tr,
                privateKey.S1,
                privateKey.S2,
                privateKey.T0,
                privateKey.T1
        ));

    byte[] signature = signer.GenerateSignature(message);
    return signature;
}

public static bool Verify (DilithiumPublicKeyParameters publicKey, byte[] message, byte[] signature)
{
    DilithiumSigner verifier = new DilithiumSigner();

    // The constructor asks for "pkEncoded" - how should the bytes be encoded?
    verifier.Init(false, new DilithiumPublicKeyParameters(
        DilithiumParameters.Dilithium5Aes,
        publicKey.GetEncoded()
        ));

    return verifier.VerifySignature(message, signature);
}

相关问题