Несовпадение подписи сообщения приватным ключом в Android Java и PHP

День добрый, господа разработчики! Прошу помощи и совета. Преамбулу, что я новенький в программировании под Android и тд и тп опустим. Итак. Разрабатываю приложение которому по протоколу обмена с API необходимо каждый свой запрос подписывать электронным приватным ключом (самоподписанным). Эта подпись на сервере проверяется с помощью PHP и публичного ключа. Приватный ключ, необходимый для подписания запроса лежит в raw в виде .pfx Вот так я его читаю:


public static PrivateKey getCompanyPrivateKey(Context myContext) {
String keyAlias = null;
KeyStore keystore = null;
PrivateKey key = null;
Enumeration aliases = null;

InputStream is;
try {
is = myContext.getResources().openRawResource(R.raw.company);
keystore = KeyStore.getInstance("PKCS12");
} catch ( KeyStoreException e) {
return null;
}
try {
assert keystore != null;
keystore.load(is, PKCS_PASSWD.toCharArray());
} catch (IOException | NoSuchAlgorithmException | CertificateException e) {
return null;
}
try {
aliases = keystore.aliases();
} catch (KeyStoreException e) {
//e.printStackTrace();
return null;
}
assert aliases != null;
while (aliases.hasMoreElements()) {
keyAlias = (String) aliases.nextElement();
}
try {
key = (PrivateKey) keystore.getKey(keyAlias, PKCS_PASSWD.toCharArray());
} catch (KeyStoreException | NoSuchAlgorithmException | UnrecoverableKeyException e ) {
return null;
}
return key;
}

Вот так подписываю:


public static String openssl_sign(PrivateKey privateKey, String plainText) {
byte[] signature = null;
try {
Signature sig = Signature.getInstance("SHA256withRSA");
sig.initSign(privateKey);
sig.update(plainText.getBytes(StandardCharsets.UTF_8));
signature = sig.sign();
} catch(Exception ex) {
ex.printStackTrace();
}
return Base64.encodeToString(signature, Base64.DEFAULT);
}

Все это работает без ошибок. Я получаю приватный ключи из .pfx и подпись строки в виде base64.

n4TLl9Lz86ufMdp4M2an/8Dwg+NuZ//+QvxSgbPZglr9af62jGKuh0omp2DWSK6BCapuSaC+c99w w5bbgnzbbajNUakLUDC2A+hgd0yn4XKOducp0TpSbadw6zprvA1UoXzUUfot/R5g8Fpmg1slrGY5 0ohB6u5EJ1wEI60yT3e1uz5KKSdJKh3pYr/WVHyfBGOvuyqRAFVkSElHh7QCuFCxxYrMQTXeOxzP YuO6u7KF69EYsKe6tlgf+cKntwtBoiQJa1nCMAYslB0DZxVDruxcKCX12yvwGoTlNgtbdADuh+WZ +SDBqdkUFoMxx6zkFJ64E4tI/UbPW+YWfOojZA==

Проблема заключается в том, что тот же самый алгоритм реализованный на PHP


$data = file_get_contents('./company.p12');
$certPassword = 'UiO389jh';
openssl_pkcs12_read($data, $certs, $certPassword);
$pkey = openssl_pkey_get_private( $certs['pkey'] );

function signJsonString( $private_key = '', $jsonString = '' ) {
$result = '';
if ( is_string( $jsonString ) && trim( strval( $jsonString ) ) != '' ) {
$binarySignature = '';
if ( openssl_sign( $jsonString, $binarySignature, $private_key, 'sha256WithRSAEncryption' ) ) {
$result = base64_encode( $binarySignature );
}
}
return $result;
}
$jsonString = '{"signupid":"2150bf6609de47a9b0233a3a458cbfbc"}';
$signature = signJsonString($pkey, $jsonString);
echo $signature;

дает совершенно другую подпись в формате base64.

wnq0zhTm3cu2zwUQR9fbyxXP8Bj07W5rHbQ22iWhcyGNWURoz1tPosw5Rdg6i/1zGI9G++8F3Lt+ XlkXtsjzNoIRyaReZ8FUhQO4CPu1eT5B4z5sEYlGbdqr81+RX2tny9K1PcS3OpMXdg80GDvBZzY9 ktldh4a66tEqoAa5sMWc91fDdmm3MTSVm0L8l5WD2mXCsBLKVLkA/ejt+HD0f5v6t1W9rbmOJBD8 hAs5pTrpRNte1fuOhgpwLUgFXzvyoPKVBdB6GQs5v1eRfkEj/hWk3/CdifPZvr1VMAOS+M4XaXGm b4n6RtknHprSpU78gF/ZAkOSvtF7j8LUIE5M6A==

Естественно алгоритмы подписи одни и теже и в Java и в PHP, .pfx-файл тоже один и тот же, сама подписываемая строка тоже абсолютно идентична в обоих случаях.

Бьюсь уже несколько месяцев. Перечитал тонны советов и подсказок. Затер stackoverflow уже до дыр, но так и не нашел конца ниточки за которую бы стоило потянуть. Во всех похожих случаях пишут уверенно только одно - подпись на PHP верна. Искать нужно в Java. Чувствую, что ларчик открывается просто, но собственных познаний в Java пока не хватает. Буду рад любой помощи и подсказке. Готов предоставить желающим помочь все необходимые файлы.

P.S Знакомый Java-программист написал на "чистой" Java пример (https://bitbucket.org/andryha/signtext/src/master/) и у него там подпись сошлась c PHP. Но на Android этого не происходит.


Ответы (0 шт):