signature.verify () всегда возвращает False - PullRequest
3 голосов
/ 30 июня 2010
 public static void main(String[] args) {
    try{
        String mod = "q0AwozeUj0VVkoksDQSCTj3QEgODomq4sAr02xMyIrWldZrNHhWfZAIcWt2MuAY3X6S3ZVUfOFXOrVbltRrO3F9Z6R8/jJIMv7wjkeVBFC5gncwGR0C3aV9gmF6II19jTKfF1sxb26iMEMAlMEOSnAAceNaJH91zBoaW7ZIh+qk=";
        String exp = "AQAB";
        byte[] modulusBytes = Base64.decodeBase64(mod.getBytes("UTF-8"));
        byte[] exponentBytes = Base64.decodeBase64(exp.getBytes("UTF-8"));
        String signedMessage = "3753e672cfb21e3c182ef2df51f19edeffb63432ed338a47251326ccc14aa63883e910a140cf313754ebc6425aad434e309307cc882da6cd4a4f9f40bd14a9823aca145e5ffc97cd63dbb5925c049282416bdfd7d74ddeef7055065210a841793fe315dff5a44af19c1522daafdc2f7e61ce5a2b42ebf79dfb086e6d210168dd";
        BigInteger modulus = new BigInteger(1, modulusBytes );               
        BigInteger exponent = new BigInteger(1, exponentBytes);
        RSAPublicKeySpec rsaPubKey = new RSAPublicKeySpec(modulus, exponent);
        KeyFactory fact = KeyFactory.getInstance("RSA");
        PublicKey pubKey = fact.generatePublic(rsaPubKey);
        Signature signature = Signature.getInstance("SHA1withRSA");
        byte[] sigBytes = hexStringToByteArray(signedMessage);
        signature.initVerify(pubKey);
        System.out.println(signature.verify(sigBytes));
    }catch(Exception e){
        System.out.println("Error: " + e.toString());
    }
}
private static byte[] hexStringToByteArray(final String encoded) {
    if ((encoded.length() % 2) != 0)
        throw new IllegalArgumentException("Input string must contain an even number of characters");

    final byte result[] = new byte[encoded.length()/2];
    final char enc[] = encoded.toCharArray();
    for (int i = 0; i < enc.length; i += 2) {
        StringBuilder curr = new StringBuilder(2);
        curr.append(enc[i]).append(enc[i + 1]);
        result[i/2] = (byte) Integer.parseInt(curr.toString(), 16);
    }
    return result;
}

Этот код всегда возвращает false.Я не уверен, куда идти отсюда.

Ответы [ 3 ]

9 голосов
/ 30 июня 2010

Там, где вы подписываете сообщение, у вас должен быть такой код:

Signature signature = Signature.getInstance("SHA1withRSA");
signature.initSign(privKey);
signature.update(message);
byte[] signatureValue = signature.sign();

Обратите внимание на массив байтов с именем signatureValue.Это фактическая подпись на данных.Это то, что вы должны предоставить verify() -метод.Сообщение, которое подписано, должно быть предоставлено при вызове update() -метода.Т.е.:

Signature signature = Signature.getInstance("SHA1withRSA");
signature.initVerify(pubKey);
signature.update(message);
bool ok = signature.verify(signatureValue);
3 голосов
/ 30 июня 2010

Я думаю, проблема в том, что вы на самом деле не даете ему сообщение для проверки.

Подпись RSA работает, сначала хешируя сообщение (это «SHA1» в «SHA1withRSA»), а затем выполняя операция с ловушкой к ней.Это операция, которую легко выполнить в одном направлении и трудно в другом, если вы не знаете секретную информацию (закрытый ключ RSA).

Для проверки сначала необходимо инвертировать математическое преобразование (потому что онов одном направлении), а затем сравните хеш, встроенный в подпись, с хешем сообщения, которое вы только что вычислили.Сама подпись не содержит сообщения;чтобы проверить подпись, вам нужна подпись и подписанное сообщение.

На уровне API похоже, что класс Signature ожидает, что вы вызовете update ссодержимое сообщения, для которого была создана эта подпись.Без этого он, вероятно, сравнивает хеш с хешем пустой строки, поэтому, если ваше первоначально подписанное сообщение также не было пустой строкой, подпись фактически недействительна.

1 голос
/ 30 июня 2010

Ты был прав, спасибо Джек. Приведенный ниже метод работает отлично (даже с ключом, созданным в .NET)! Я надеюсь, что это помогает другим.

public static void main(String[] args) {
    try{
        String userID = "189711";
        String companyCode = "ILIKEPIZZA";
        String combine = userID + "." + companyCode;
        String mod = "q0AwozeUj0VVkoksDQSCTj3QEgODomq4sAr02xMyIrWldZrNHhWfZAIcWt2MuAY3X6S3ZVUfOFXOrVbltRrO3F9Z6R8/jJIMv7wjkeVBFC5gncwGR0C3aV9gmF6II19jTKfF1sxb26iMEMAlMEOSnAAceNaJH91zBoaW7ZIh+qk=";
        String exp = "AQAB";
        byte[] modulusBytes = Base64.decodeBase64(mod.getBytes("UTF-8"));
        byte[] exponentBytes = Base64.decodeBase64(exp.getBytes("UTF-8"));
        String sign = "3753e672cfb21e3c182ef2df51f19edeffb63432ed338a47251326ccc14aa63883e910a140cf313754ebc6425aad434e309307cc882da6cd4a4f9f40bd14a9823aca145e5ffc97cd63dbb5925c049282416bdfd7d74ddeef7055065210a841793fe315dff5a44af19c1522daafdc2f7e61ce5a2b42ebf79dfb086e6d210168dd";
        BigInteger modulus = new BigInteger(1, modulusBytes );               
        BigInteger exponent = new BigInteger(1, exponentBytes);
        RSAPublicKeySpec rsaPubKey = new RSAPublicKeySpec(modulus, exponent);
        KeyFactory fact = KeyFactory.getInstance("RSA");
        PublicKey pubKey = fact.generatePublic(rsaPubKey);
        Signature signature = Signature.getInstance("SHA1withRSA");
        byte[] sigBytes = hexStringToByteArray(sign);
        signature.initVerify(pubKey);
        signature.update(combine.getBytes("UTF-8"));
        System.out.println(signature.verify(sigBytes));
    }catch(Exception e){
        System.out.println("Error: " + e.toString());
    }
}
...