首页 > 解决方案 > 如何将时间戳放在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 谁能帮忙?)

标签: androidkotlinopenssltimestampprivate-key

解决方案


在 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)

推荐阅读