4

最近、ブラインドサインについて耳にしました。それらがどのように機能するかについてのウィキペディアの記事を見ましたが、実装したくありません。ブラインド署名を実装し、ファイルが署名されていることを確認するために、どのライブラリ (できれば Linux および Windows と互換性がある) を使用できますか?

openssl の man ページを見てみましたが、ブラインド署名をサポートしているとは思いませんhttp://www.openssl.org/docs/apps/dgst.html

私は自分のアプリを C++ または .NET のいずれかで実装でき、プロセスの生成とその出力の解析に問題はありませんが、ソフトウェアよりも lib が優先されます。

4

2 に答える 2

1

アプリを C++ または .NET のいずれかで実装できます...署名してやみくもに検証するライブラリまたはソフトウェアは何ですか?

これがCrypto ++ベースの回答です。Crypto++ は、Wei Dai によって書かれた暗号方式のクラス ライブラリです。この例はRaw RSA | ウィキのブラインド署名。

C++11 暗号および TLS ライブラリであるJack Lloyd のBotanは、ネイティブのブラインド署名をサポートしている可能性があります。

Crypto++ にはブラインド署名クラスがありません。以下の方法は、Blind Signaturesで詳述されている基本的なアルゴリズムに従います。ただし、s(s'(x)) = xクロスチェックを適用する点で Wikipedia とは異なります。クロスチェックはChaum の元の論文にありましたが、wiki 記事にはありません。Chaum の論文やウィキペディアとの 2 番目の違いは、以下のコードH(m)ではm. それは 1979 年の Rabinによるものです。

ブラインド RSA 署名のパディング スキームの使いやすさに従って、最初にパディング関数を適用することをお勧めします。または実際の RSA ブラインド署名Is there a standard padding/format for RSA Blind Signaturesも参照してください。


#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
于 2017-12-18T05:00:50.780 に答える
-1

ブラインド署名を特別にサポートする必要はありません。メッセージに署名して検証できる必要があるだけです。ブラインド部分は、非対称暗号を使用するシステム次第です。受信したコンテンツに特別な形式で署名するだけでは、ブラインド署名と見なされ、別の場所に移動する前にデータが通過したことを示します。RSAを使用していないことを確認してください

編集

この回答のコメントの拡張された議論によると、具体的に話している内容によっては、上記のテキストが誤解を招く可能性があります。この回答へのコメントで説明されているようにブラインド署名を完了する場合は、実際には特別なサポートが必要になります。レビューおよびテストされたものが見つからない場合は、独自のものを実装して GitHub などに投稿するのは、クールな演習またはプロジェクトになると思います。

于 2013-10-23T21:45:24.597 に答える