我最近听说盲签名。我看到了关于它们如何工作的维基百科文章,但不想实现它。我可以使用哪些库(最好与 linux 和 windows 兼容)来实现盲签名并验证文件是否已签名?
我尝试查看 openssl 手册页,但我认为它不支持盲签名http://www.openssl.org/docs/apps/dgst.html
我可以在 C++ 或 .NET 中实现我的应用程序,并且在生成过程和解析它们的输出时没有问题,但是 lib 比软件更受欢迎。
我最近听说盲签名。我看到了关于它们如何工作的维基百科文章,但不想实现它。我可以使用哪些库(最好与 linux 和 windows 兼容)来实现盲签名并验证文件是否已签名?
我尝试查看 openssl 手册页,但我认为它不支持盲签名http://www.openssl.org/docs/apps/dgst.html
我可以在 C++ 或 .NET 中实现我的应用程序,并且在生成过程和解析它们的输出时没有问题,但是 lib 比软件更受欢迎。
我可以在 C++ 或 .NET 中实现我的应用程序......什么库或软件可以盲目地签名和验证?
这是一个基于Crypto++的答案。Crypto++是戴伟编写的密码方案类库。该示例取自Raw RSA | 维基上的盲签名。
Jack Lloyd 的Botan是一个 C++11 加密和 TLS 库,可能具有原生盲签名支持。
Crypto++ 缺少盲签名类。下面的方法遵循Blind Signatures中详述的基本算法。但是,它与维基百科的不同之处在于应用了s(s'(x)) = x
交叉检查。交叉检查出现在Chaum 的原始论文中,但在 wiki 文章中没有。与 Chaum 的论文和维基百科的第二个区别是,下面的代码使用H(m)
而不是m
. 这要归功于1979 年的拉宾。
您可能希望根据盲 RSA 签名中填充方案的可用性首先应用填充函数?或RSA 盲签名在实践中。另请参阅是否有 RSA 盲签名的标准填充/格式?
#include "cryptlib.h"
#include "integer.h"
#include "nbtheory.h"
#include "osrng.h"
#include "rsa.h"
#include "sha.h"
using namespace CryptoPP;
#include <iostream>
#include <stdexcept>
using std::cout;
using std::endl;
using std::runtime_error;
int main(int argc, char* argv[])
{
// Bob artificially small key pair
AutoSeededRandomPool prng;
RSA::PrivateKey privKey;
privKey.GenerateRandomWithKeySize(prng, 64);
RSA::PublicKey pubKey(privKey);
// Convenience
const Integer& n = pubKey.GetModulus();
const Integer& e = pubKey.GetPublicExponent();
const Integer& d = privKey.GetPrivateExponent();
// Print params
cout << "Pub mod: " << std::hex << pubKey.GetModulus() << endl;
cout << "Pub exp: " << std::hex << e << endl;
cout << "Priv mod: " << std::hex << privKey.GetModulus() << endl;
cout << "Priv exp: " << std::hex << d << endl;
// For sizing the hashed message buffer. This should be SHA256 size.
const size_t SIG_SIZE = UnsignedMin(SHA256::BLOCKSIZE, n.ByteCount());
// Scratch
SecByteBlock buff1, buff2, buff3;
// Alice original message to be signed by Bob
SecByteBlock orig((const byte*)"secret", 6);
Integer m(orig.data(), orig.size());
cout << "Message: " << std::hex << m << endl;
// Hash message per Rabin (1979)
buff1.resize(SIG_SIZE);
SHA256 hash1;
hash1.CalculateTruncatedDigest(buff1, buff1.size(), orig, orig.size());
// H(m) as Integer
Integer hm(buff1.data(), buff1.size());
cout << "H(m): " << std::hex << hm << endl;
// Alice blinding
Integer r;
do {
r.Randomize(prng, Integer::One(), n - Integer::One());
} while (!RelativelyPrime(r, n));
// Blinding factor
Integer b = a_exp_b_mod_c(r, e, n);
cout << "Random: " << std::hex << b << endl;
// Alice blinded message
Integer mm = a_times_b_mod_c(hm, b, n);
cout << "Blind msg: " << std::hex << mm << endl;
// Bob sign
Integer ss = privKey.CalculateInverse(prng, mm);
cout << "Blind sign: " << ss << endl;
// Alice checks s(s'(x)) = x. This is from Chaum's paper
Integer c = pubKey.ApplyFunction(ss);
cout << "Check sign: " << c << endl;
if (c != mm)
throw runtime_error("Alice cross-check failed");
// Alice remove blinding
Integer s = a_times_b_mod_c(ss, r.InverseMod(n), n);
cout << "Unblind sign: " << s << endl;
// Eve verifies
Integer v = pubKey.ApplyFunction(s);
cout << "Verify: " << std::hex << v << endl;
// Convert to a string
size_t req = v.MinEncodedSize();
buff2.resize(req);
v.Encode(&buff2[0], buff2.size());
// Hash message per Rabin (1979)
buff3.resize(SIG_SIZE);
SHA256 hash2;
hash2.CalculateTruncatedDigest(buff3, buff3.size(), orig, orig.size());
// Constant time compare
bool equal = buff2.size() == buff3.size() && VerifyBufsEqual(
buff2.data(), buff3.data(), buff3.size());
if (!equal)
throw runtime_error("Eve verified failed");
cout << "Verified signature" << endl;
return 0;
}
这是构建和运行程序的结果:
$ g++ blind.cxx ./libcryptopp.a -o blind.exe
$ ./blind.exe
Pub mod: bbf62585f8486acbh
Pub exp: 11h
Priv mod: bbf62585f8486acbh
Priv exp: 31c1280c6bb08635h
Message: 736563726574h
H(m): 2bb80d537b1da3e3h
Random: 7db0ecdb0a09fad5h
Blinded msg: a8bf62a25b7b4b53h
Blind sign: 2646ab6b9d5b48dfh
Check sign: a8bf62a25b7b4b53h
Unblind sign: 418d211b9cbb2d00h
Verify: 2bb80d537b1da3e3h
Verified signature
您不需要任何对盲签名的特殊支持。您只需要能够签署和验证消息。盲部分取决于使用非对称密码的系统。简单地以特殊格式对您收到的内容进行签名可能构成盲签名,表明数据在转到其他地方之前已通过您。只要确保你不使用 RSA
编辑
根据此答案评论中的扩展讨论,上述文字可能会产生误导,具体取决于您具体谈论的内容。如果您打算按照此答案的评论中所述完成盲签名,那么您实际上将需要特殊支持。我会说,如果你找不到经过审查和测试的东西,那将是一个很酷的练习或项目来实现你自己的并将其发布在 GitHub 等上。