Есть некие данные в виде массива байт byte[] data, подпись(signature) в виде Base64 строки и публичный ключ(publicKey) - строка следующего вида:
Код: Выделить всё
-----BEGIN PUBLIC KEY-----
Тут сам ключ в виде Base64 строки
-----END PUBLIC KEY-----
Я делаю следующие действия:
Для начала декодирую подпись в массив байт и создаю объект PublicKey:
Код: Выделить всё
byte[] decodedSign= Base64.decode(signature, Base64.DEFAULT);
int pos1 = publicKey.indexOf(HEADER);
int pos2 = publicKey.indexOf(FOOTER, pos1 + 1);
String keyStr = publicKey.substring(pos1 + HEADER.length(), pos2).replace("\n", "");
byte[] decodedKey= Base64.decode(keyStr, Base64.DEFAULT);
EncodedKeySpec bobPubKeySpec = new X509EncodedKeySpec(decodedKey);
KeyFactory keyFactory = KeyFactory.getInstance(ALGORITHM);
PublicKey bobPubKey = keyFactory.generatePublic(bobPubKeySpec);Код: Выделить всё
static String HEADER = "-----BEGIN PUBLIC KEY-----\n";
static String FOOTER = "-----END PUBLIC KEY-----\n";
static String ALGORITHM = "DSA";Затем создаю объект Signature, инициализирую, помещаю в него данные для проверки и затем провожу саму проверку
Код: Выделить всё
Signature sig = Signature.getInstance(ALGORITHM);
sig.initVerify(bobPubKey);
sig.update(data);
boolean result = sig.verify(decodedSign)Портирую приложение с Window Phone на Android, На WP используется библиотека BouncyCastle, однако не вижу необходимости импортировать целую библиотеку из за одной проверки.
Есть возможность проверить через отладку правильность входных данных.
- То, что нужно использовать X509EncodedKeySpec уверен на 100%, так как создание самого ключа происходит без проблем и на WP также создается ключ X509.
- Залез внутрь класса ключа и вытащил список DSA параметров G,P,Q и Y на обоих платформах совершенно идентичны.
- Base64 строки из data также идентичны. Строки сверялись не на глаз а посимвольно с помощью программы.
Единственное подозрение вызывает использование подписи, так как в WP вместо проверки через массив байт используется следующее
Код: Выделить всё
DsaSigner dsaSigner = new DsaSigner();
// Инициализация dsaSigner при помощи публичного ключа
Asn1InputStream asn1is = new Asn1InputStream(signature);
Asn1Sequence s = (Asn1Sequence)asn1is.ReadObject();
BigInteger[] sig = new BigInteger[2];
sig[0] = ((DerInteger)s[0]).Value;
sig[1] = ((DerInteger)s[1]).Value;
result = dsaSigner.VerifySignature(data, sig[0], sig[1]);