1

PHP アプリケーションに送信する前に、javascript でメッセージに署名しようとしています。PHP アプリケーションは、署名が偽でないことを確認するために署名をチェックする必要があります。

JavaScript では cryptico.js を使用します。

これは、メッセージに署名するための js 関数です。

var sign = function(passphrase, text) {
    signingkey = cryptico.generateRSAKey(passphrase, 2048);
    signString = cryptico.b16to64(signingkey.signString(text, "sha256"));
    return signString;
}

これは、公開鍵を取得するための関数です。

var getPublicKey = function(passphrase) {
 var rsaKey = cryptico.generateRSAKey(passphrase, 2048);
 return = cryptico.publicKeyString(rsaKey);
}

たとえば、メッセージ「message」とパスフレーズ「test2」の公開鍵と署名は次のとおりです。

qH/J3/gvF/h5U02uPyC9Qzn/hHEV5DzB9nFfqk5zbQqHdInVe4sfL+npa+4fjLGrBU30Iuvcr+o9paEjzpH5dY48cq6JHqz1RyJ0CQIc2Jr5+sS4eL1ZIjxWlyN1pKMR+4aE2rlDAad56Ad1cytiaHuVvyK/gdtbKiuGroSQhJ1EVfZ60m3NIqnqmpi5Zdsnmzny4VH/d66BcGXxGaGaUaqFn0WTypuwIMZMMtzZEK7peKoaW4H4rfkfdrKcD8AaT+z9v5lLGkTl0NcZZ4LN9sSUzsHNfyAFK6cSXo/73z0tDAlGb5K+yWV6UHoYW1rcoIsxlNRZM6/6FYgMXbbfow==

XbF4O6v6oadEQGtdpQ7d54Q2JB9/ZEXEUH3S1FMn4E/PSqk7HLXjG4tNfuiUBa5eS8kYV49gwC8Yr+mn6YUAHt+K9lHPSsmltWoiHNOaas4aqai9nlyeft4TYYhP+GYbQfw+3n2TcO39s6M0vw0m0a8AX9JfF02JwCUhP4bu4dzG6Bl5dj000TbUkric14Jyurp8OHmmMvKW62TvXPhNOW39+wS1Qkfn9Bxmzi8UEVSVe3wP45JWZNgmgeGnpubDhD05FJEDErfVtZ/DRKD81q5YRd4X4cCkeDPDcJLgKW1jkCsA7yBqESXPDSkkrVUM06A9qMFUwk4mRI88fZ8ryQ==

PHPで確認する方法を教えてください。

私は次のようなことを試しました:

$rsa = new Crypt_RSA();
$rsa->loadKey('qH/J3/gvF/h5U02uPyC9Qzn/hHEV5DzB9nFfqk5zbQqHdInVe4sfL+npa+4fjLGrBU30Iuvcr+o9paEjzpH5dY48cq6JHqz1RyJ0CQIc2Jr5+sS4eL1ZIjxWlyN1pKMR+4aE2rlDAad56Ad1cytiaHuVvyK/gdtbKiuGroSQhJ1EVfZ60m3NIqnqmpi5Zdsnmzny4VH/d66BcGXxGaGaUaqFn0WTypuwIMZMMtzZEK7peKoaW4H4rfkfdrKcD8AaT+z9v5lLGkTl0NcZZ4LN9sSUzsHNfyAFK6cSXo/73z0tDAlGb5K+yWV6UHoYW1rcoIsxlNRZM6/6FYgMXbbfow=='); // public key
echo $rsa->verify('message', 'XbF4O6v6oadEQGtdpQ7d54Q2JB9/ZEXEUH3S1FMn4E/PSqk7HLXjG4tNfuiUBa5eS8kYV49gwC8Yr+mn6YUAHt+K9lHPSsmltWoiHNOaas4aqai9nlyeft4TYYhP+GYbQfw+3n2TcO39s6M0vw0m0a8AX9JfF02JwCUhP4bu4dzG6Bl5dj000TbUkric14Jyurp8OHmmMvKW62TvXPhNOW39+wS1Qkfn9Bxmzi8UEVSVe3wP45JWZNgmgeGnpubDhD05FJEDErfVtZ/DRKD81q5YRd4X4cCkeDPDcJLgKW1jkCsA7yBqESXPDSkkrVUM06A9qMFUwk4mRI88fZ8ryQ==') ? 'verified' : 'unverified';

署名や公開鍵が php 用に正しくフォーマットされていないと思います。何か案が?

前もって感謝します、

[編集] 署名が正しいかどうかわかりません。js 関数を使用するcryptico.b64to16(signature)と、署名は次のようになります。

5db1783babfaa1a744406b5da50edde78436241f7f6445c4507dd2d45327e04fcf4aa93b1cb5e31b8b4d7ee89405ae5e4bc918578f60c02f18afe9a7e985001edf8af651cf4ac9a5b56a221cd39a6ace1aa9a8bd9e5c9e7ede1361884ff8661b41fc3ede7d9370edfdb3a334bf0d26d1af005fd25f174d89c025213f86eee1dcc6e81979763d34d136d492b89cd78272baba7c3879a632f296eb64ef5cf84d396dfdfb04b54247e7f41c66ce2f141154957b7c0fe3925664d82681e1a7a6e6c3843d3914910312b7d5b59fc344a0fcd6ae5845de17e1c0a47833c37092e0296d63902b00ef206a1125cf0d2924ad550cd3a03da8c154c24e26448f3c7d9f2bc9

$rsa->verify の param key のフォーマットがわかりません。プレフィックス ssh-rsa を追加しようとしました。しかし、それはうまくいきません。

そこで、to 署名形式と to キーを試してみました。メッセージは毎回「未確認」です

4

1 に答える 1

3

ありがとう@neubert、それはPSS署名によるものです。

だからここに解決策があります。

私が使う:

  • phpseclib : メッセージの検証に使用される PHP ライブラリ
  • jsrsasign : メッセージの署名に使用される JS ライブラリ
  • jsencrypt : 秘密鍵と公開鍵を作成するための JS lib

まず、JS でキーを生成します。

crypt = new JSEncrypt({default_key_size: 512});
var key = crypt.getKey();

var publicKey = key.getPublicKey();
var privateKey = key.getPrivateKey();

次に、署名を作成します。

var rsa = new RSAKey();
rsa.readPrivateKeyFromPEMString(privateKey);
var hSig = rsa.signStringPSS('message', 'sha1');
var signature = linebrk(hSig, 64);
console.log(signature);

デフォルトでは、署名は適切な形式ではありません。関数 base64Chars を使用して base 64 で hSig をエンコードする必要があります。

var base64Chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';
b16to64 = function(h) {
    var i;
    var c;
    var ret = "";
    if(h.length % 2 == 1)
    {
        h = "0" + h;
    }
    for (i = 0; i + 3 <= h.length; i += 3)
    {
        c = parseInt(h.substring(i, i + 3), 16);
        ret += base64Chars.charAt(c >> 6) + base64Chars.charAt(c & 63);
    }
    if (i + 1 == h.length)
    {
        c = parseInt(h.substring(i, i + 1), 16);
        ret += base64Chars.charAt(c << 2);
    }
    else if (i + 2 == h.length)
    {
        c = parseInt(h.substring(i, i + 2), 16);
        ret += base64Chars.charAt(c >> 2) + base64Chars.charAt((c & 3) << 4);
    }
    while ((ret.length & 3) > 0) ret += "=";
    return ret;
}

最後に、PHP で検証します。署名と公開鍵が同じ名前の vars に格納されていると仮定します。

$rsa = new Crypt_RSA();
$rsa->loadKey($publickey); // public key;
echo $rsa->verify('message', base64_decode($signature)) ? 'verified' : 'unverified';
于 2014-05-29T20:18:41.290 に答える