У меня есть некоторые данные, которые я подписываю на iOS с помощью SecKeyRawSign
, используя закрытый ключ Elliptic Curve. Однако проверка данных в Java с использованием Signature.verify()
возвращает false
Данные представляют собой случайное 64-битное целое число, разбитое на байты следующим образом.
uint64_t nonce = (some 64 bit integer)
NSData *nonceData = [NSData dataWithBytes: &nonce length: sizeof(nonce)];
Из этих данных я создаю дайджест SHA256.
int digestLength = CC_SHA256_DIGEST_LENGTH;
uint8_t *digest = malloc(digestLength);
CC_SHA256(nonceData.bytes, (CC_LONG)nonceData.length, digest);
NSData *digestData = [NSData dataWithBytes:digest length:digestLength];
а затем подписать его закрытым ключом
size_t signedBufferSize = kMaxCipherBufferSize;
uint8_t *signedBuffer = malloc(kMaxCipherBufferSize);
OSStatus status = SecKeyRawSign(privateKeyRef,
kSecPaddingPKCS1SHA256,
(const uint8_t *)digestData.bytes,
digestData.length,
&signedBuffer[0],
&signedBufferSize);
NSData *signedData = nil;
if (status == errSecSuccess) {
signedData = [NSData dataWithBytes:signedBuffer length:signedBufferSize];
}
Все работает нормально.
Затем на Java-сервере я пытаюсь проверить подписанные данные.
PublicKey publicKey = (a public key sent from iOS, X509 encoded)
Long nonce = (64 bit integer sent from iOS)
String signedNonce = (base64 encoded signed data)
ByteBuffer buffer = ByteBuffer.allocate(Long.BYTES);
buffer.putLong(nonce);
byte[] nonceBytes = buffer.array();
byte[] signedNonceBytes = Base64.getDecoder().decode(signedNonce.getBytes());
Signature signer = Signature.getInstance( "SHA256withECDSA" );
signer.initVerify( publicKey );
signer.update( nonceBytes );
Boolean isVerified = signer.verify( signedNonceBytes );
В этот момент signer.verify()
возвращает false
Я также пытался подписать простые данные вместо дайджеста SHA256, но это тоже не работает.
Что мне не хватает? Правильно ли я подписываю данные? Я использую правильный отступ? Нужно ли что-то еще сделать с данными, чтобы иметь возможность проверить их с помощью алгоритма SHA256withECDSA
?
[NSData dataWithBytes: &nonce...
обращается к фактической необработанной памяти, в то время как сторона Java может видеть одноразовый номер в более общем сетевом порядке байтов. Поэтому попробуйте, работает ли одноразовый номер 0. - person mschmidt   schedule 24.05.2018nonceData
этот порядок сохраняется. Однако на стороне JavaByteBuffer
по умолчанию имеет обратный порядок байтов. Итак, вам нужно добавить:buffer.order(ByteOrder.LITTLE_ENDIAN);
- person Codo   schedule 29.05.2018