android - 如何将时间戳放在android生成的加密签名中
问题描述
我所拥有的是没有页眉、页脚和空格的私钥(这是一个测试)
MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQg0m4yLz+sdzZtBG9Q3HQ9++wcfq1O4hOWgSBMb/A6eijyhRANCAAQeB0fBl2D7HZOKVBjpPiU2jabzNxQU4ZYrJ+MSA3LpzZxmRk2JaFHNujjkJghQT19HHjg3Fnkb8Y9oIhB9neXBI
android中的这段代码会生成所需格式的签名。
val signatureSHA256 = Signature.getInstance("SHA256withECDSA")
val encoded = Base64.decode(privateKeyHere, Base64.DEFAULT)
val privateKey: PrivateKey = KeyFactory.getInstance("EC").generatePrivate(PKCS8EncodedKeySpec(encoded))
signatureSHA256.initSign(privateKey)
val finalSignature = signatureSHA256.sign().toHexString()
//Somewhere
fun ByteArray.toHexString() = joinToString("") { "%02x".format(it) }
以及返回时间戳的函数:
fun getXTimestamp(): Long {
return (System.currentTimeMillis() / 1000L)
}
从 android 我得到 finalSignature 和 getXTimestamp() 我需要在 php 脚本中验证我的签名:
$timestamp = '1625730735';
$public_key = "
-----BEGIN PUBLIC KEY-----
MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEHgdHwZdg+x2TilQY6T4lNo2m8zcU
FGWKyfjEgNy6c2cZkZNiWhRzbo45CYIUE9fRx44NxZ5G/GPaCIQfZ3lwSA==
-----END PUBLIC KEY-----
";
//hex2bin("finalSignature")
$sign = hex2bin("3045022048011d511094a5270c528ca5064b07084e36ccfd2ee3f5e1e20278fb5d83cdba022100d71a0096ef2c6288554a51017a89374b18c7e84ba7031a43d67f53d7ce89152c");
$result = openssl_verify($timestamp, $sign, $public_key, OPENSSL_ALGO_SHA256);
print $result;
现在从控制台启动的 php 脚本返回 0 但应该返回 1。我想我应该以某种方式更新或将时间戳放在签名中。我试图将它作为字节放入 update() 中,但仍然得到 0 谁能帮忙?)
解决方案
在 PHP 端(“验证”),您使用“时间戳”作为文本字符串作为 openssl_verify 函数的输入。
在 Kotlin 方面,您需要执行相同的操作 - 将时间戳作为字符串并将其用作 sign.update 调用的输入,其中 [Pseudo-code] timestamp-string.getBytes(StandardCharset.UTF8) 作为输入。
由于我不熟悉 Kotlin,因此我使用@Andrej Kijonok 评论中的代码来解决问题:-)
val signatureTimestamp = getXTimestamp().toString().toByteArray(Charsets.UTF_8)
signatureSHA256.initSign(privateKey)
signatureSHA256.update(signatureTimestamp)