Проверка подписи по ГОСТ Р 34.10-2001. Java.
Добрый день!
Имеется - ЭЦП по ГОСТ Р 34.10-2001 созданной "Рутокеном ЭЦП", открытый ключ, подписываемый хеш.
Требутеся - Исходя из имеющихся данных проверить ЭЦП. Платформа Java.
Для реализации задачи использовалась библиотека Bouncy Castle. Данные для создания нужной элиптической кривой взяты из примеров, написанных на php и c#, Bouncy Castle предоставляет нужную кривую - "gostR3410_2001_CryptoPro_A". Данные для примера работы проверки подписи взяты из примера написанного на php.
Сам код:
import java.math.BigInteger;
import java.security.InvalidKeyException;
import java.security.KeyFactory;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
import java.security.PublicKey;
import java.security.Security;
import java.security.Signature;
import java.security.SignatureException;
import java.security.spec.InvalidKeySpecException;
import org.apache.commons.codec.DecoderException;
import org.apache.commons.codec.binary.Hex;
import org.bouncycastle.asn1.cryptopro.CryptoProObjectIdentifiers;
import org.bouncycastle.asn1.cryptopro.ECGOST3410NamedCurves;
import org.bouncycastle.crypto.params.ECDomainParameters;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.bouncycastle.jce.spec.ECParameterSpec;
import org.bouncycastle.jce.spec.ECPublicKeySpec;
import org.bouncycastle.math.ec.ECCurve;
public class RuTokenVerificationTest {
public static void main(final String[] args) throws NoSuchProviderException, NoSuchAlgorithmException,
InvalidKeySpecException, InvalidKeyException, SignatureException, DecoderException {
final String publicKey = "16E3585053A4BE8546FB3475F1CBDD7FF1A2C9BC886BD8C1E9214C2C2A4681226BFBA33C9F50F8F952091306C5BE17E5447D82F8EFBC0784E10234E7D7CA71A0";
final String hash = "5D5FE1DD044A577C8B6580F49394CF4B4EF2D617C60C9AB6CDF2AC14BAB359C7";
final String sign = "1B432A390D2871EEF2A4F4A5A607938DC4EBE6D2871A18133578F701851F37C22BE1AFE68F9FE586F36C626FABF9DFC316491742EC793388EFADDE81FE34F3DC";
final BigInteger x = new BigInteger(publicKey.substring(0, 64), 16);
final BigInteger y = new BigInteger(publicKey.substring(64), 16);
Security.addProvider(new BouncyCastleProvider());
final Signature sgr = Signature.getInstance("ECGOST3410", "BC");
final KeyFactory f = KeyFactory.getInstance("ECGOST3410", "BC");
final ECDomainParameters parameters = ECGOST3410NamedCurves.getByOID(CryptoProObjectIdentifiers.gostR3410_2001_CryptoPro_A);
final ECCurve curve = parameters.getCurve();
final ECParameterSpec spec = new ECParameterSpec(curve, parameters.getG(), parameters.getN());
final ECPublicKeySpec pubKey = new ECPublicKeySpec(curve.createPoint(x, y, false), spec);
final PublicKey pk = f.generatePublic(pubKey);
sgr.initVerify(pk);
sgr.update(hash.getBytes());
System.out.println(sgr.verify(Hex.decodeHex(sign.toCharArray())));
}
}
Результат работы - false. Т.е. проверка не проходит. Никак не могу разобраться почему... Пробовал и реальные данные, созданные рутокеном, - тот же результат.
Может быть что-то в форматах данных, в частности, хеша, я верно делаю когда просто беру байтовый массив хеша и передаю его на проверку? Может его нужно представить в каком-то другом виде? Тоже самое с подписью. Помогите понять в чем ошибка.