提问者:小点点

带ASP.NET和充气城堡的CRYSTALS-DILITHIUM数字签名


我正在用ASP.NET编写一个点对点文件共享系统。客户端需要能够验证他们的文件来自值得信赖的作者。客户端拥有他们信任的作者的公钥,作者应该对他们共享的文件进行数字签名。

我想使用CRYSTALS-DILITHIUM来生成和验证这些签名,并且正在使用Bouncy Castle的.NET库v2.2.0来实现算法。

我怎样才能:

  1. 生成一个新的密钥对
  2. 使用私钥签署消息
  3. 使用公钥验证消息

这是到目前为止我的示例代码:

请注意,某些项目,例如new DilithiumPrivate ateKeyParameters(…)的参数丢失了,因为我不知道那里应该有什么。

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);
}

共1个答案

匿名用户

这是签名和验证的工作示例-没有什么是一点点类型转换无法修复的!

我发现有用的链接:

  1. Bouncy Castle使用C#签署和验证SHA256证书
  2. 如何使用BouncyCastle从字符串生成私钥
  3. Bouncy Castle C#-从字节数组获取公钥对象
  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

我需要将键维护为Dili的… KeyParameters,而不是byte[]s或ICypherKeyParameters。这使我可以访问正确的Rho、K等属性和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);
}