1

RSA 経由でサーバーの ID を確認したいシステムを作成していますが、サーバーにクライアントのメッセージを適切に復号化させることができないようです。

公開鍵と秘密鍵はアレイのスロット 0 にあり、mod はスロット 1 にあるため、正しくセットアップされています。

クライアント側のコード

int keyLength = 3072 / 8;//RSA key size
byte[] data = new byte[keyLength];

//Generate some random data. Note that
//Only the fist half of this will be used.
new SecureRandom().nextBytes(data);

int serverKeySize = in.readInt();
if (serverKeySize != keyLength) {//Definitely not the right heard
    return false;
}

//Take the server's half of the random data and pass ours
in.readFully(data, keyLength / 2 , keyLength / 2);

//Encrypt the data
BigInteger[] keys = getKeys();
BigInteger original = new BigInteger(data);
BigInteger encrypted = original.modPow(keys[0], keys[1]);
data = encrypted.toByteArray();

out.write(data);

//If the server's hash doesn't match, the server has the wrong key!
in.readFully(data, 0, data.length);

BigInteger decrypted = new BigInteger(data);

return original.equals(decrypted);

サーバー側コード

int keyLength = 3072 / 8;//Key length
byte[] data = new byte[keyLength];

//Send the second half of the key
out.write(data, keyLength / 2, keyLength / 2);
in.readFully(data);

BigInteger[] keys = getKeys();
BigInteger encrypted = new BigInteger(data);
BigInteger original = encrypted.modPow(keys[0], keys[1]);
data = original.toByteArray();

out.write(data);

私の知る限り、実装は正しいですが、正しい出力が生成されないようです。いいえ、さまざまな理由で暗号を使用したくありません。

4

1 に答える 1

2

説明されていない重要な詳細がいくつかあります。RSA を適用するデータは、0 <= x < n の BigInteger x としてエンコードする必要があります。ここで、n はモジュラスです。あなたはそれをしていません。実際、データ配列全体にランダムなデータを入力しているため、それを保証することはできません。PKCS#1 パディング アルゴリズムは、これを正しく行うように設計されていますが、独自にローリングしているため、コードでこれを修正する必要があります。また、BigInteger(byte[])コンストラクターがどのようにBigInteger.toByteArray()整数をデコード/エンコードするかを注意深く調べてください。多くの人は単純に base 256 エンコーディングを期待しており、BigInteger が負の整数にも対応しなければならないことを忘れています。これは、ASN.1 DER 整数規則を使用して行われます。正の整数の上位バイトが >= 128 になる場合は、先行ゼロ バイトが追加されます。

于 2012-11-22T14:21:12.910 に答える