feat: RSASSA-PSS Using SHA-512で署名の生成ができるように

This commit is contained in:
usbharu 2024-09-23 17:52:06 +09:00
parent f393c6b622
commit e85e5d10f9
Signed by: usbharu
GPG Key ID: 95CBCF7046307B77
4 changed files with 109 additions and 10 deletions

View File

@ -1,6 +0,0 @@
package dev.usbharu.httpsignature.v2
enum class SignatureAlgorithm(val value: String) {
;
}

View File

@ -23,10 +23,10 @@ class SignatureBase() {
fun generateSignatureParameterString(signatureParameter: SignatureParameter): String {
return listOfNotNull(
list.keys.joinToString(" ", "(", ")"),
signatureParameter.algorithm?.let { algorithm -> "alg=\"${algorithm.value}\"" },
signatureParameter.algorithm?.let { algorithm -> "alg=\"${algorithm}\"" },
signatureParameter.keyId?.let { keyId -> "keyid=\"$keyId\"" },
signatureParameter.created?.let { created -> "created=$created" },
signatureParameter.expires?.let { expires -> "expires=$expires" },
signatureParameter.created?.let { created -> "created=${created.epochSecond}" },
signatureParameter.expires?.let { expires -> "expires=${expires.epochSecond}" },
signatureParameter.nonce?.let { nonce -> "nonce=\"$nonce\"" },
signatureParameter.tag?.let { tag -> "tag=\"$tag\"" },
).joinToString(";")

View File

@ -3,10 +3,11 @@ package dev.usbharu.httpsignature.v2
import java.time.Instant
data class SignatureParameter(
val algorithm: SignatureAlgorithm? = null,
val algorithm: String? = null,
val keyId: String? = null,
val created: Instant? = null,
val expires: Instant? = null,
val nonce: String? = null,
val tag: String? = null,
)

View File

@ -1,11 +1,18 @@
package dev.usbharu.httpsignature.v2
import org.junit.jupiter.api.Assertions.assertEquals
import org.junit.jupiter.api.Assertions.assertTrue
import org.junit.jupiter.api.Test
import java.security.KeyFactory
import java.security.Signature
import java.security.interfaces.RSAPrivateKey
import java.security.spec.MGF1ParameterSpec
import java.security.spec.PKCS8EncodedKeySpec
import java.security.spec.PSSParameterSpec
import java.security.spec.X509EncodedKeySpec
import java.time.Instant
import java.util.*
import kotlin.math.sign
class GenerateSignatureTest {
@ -75,4 +82,101 @@ class GenerateSignatureTest {
println(sign.signature)
println(sign.signatureInput)
}
@Test
fun test2() {
val key = KeyFactory.getInstance("RSASSA-PSS").generatePrivate(
PKCS8EncodedKeySpec(
Base64.getDecoder().decode(
"MIIEvgIBADALBgkqhkiG9w0BAQoEggSqMIIEpgIBAAKCAQEAr4tmm3r20Wd/Pbqv" +
"P1s2+QEtvpuRaV8Yq40gjUR8y2Rjxa6dpG2GXHbPfvMs8ct+Lh1GH45x28Rw3Ry5" +
"3mm+oAXjyQ86OnDkZ5N8lYbggD4O3w6M6pAvLkhk95AndTrifbIFPNU8PPMO7Oyr" +
"FAHqgDsznjPFmTOtCEcN2Z1FpWgchwuYLPL+Wokqltd11nqqzi+bJ9cvSKADYdUA" +
"AN5WUtzdpiy6LbTgSxP7ociU4Tn0g5I6aDZJ7A8Lzo0KSyZYoA485mqcO0GVAdVw" +
"9lq4aOT9v6d+nb4bnNkQVklLQ3fVAvJm+xdDOp9LCNCN48V2pnDOkFV6+U9nV5oy" +
"c6XI2wIDAQABAoIBAQCUB8ip+kJiiZVKF8AqfB/aUP0jTAqOQewK1kKJ/iQCXBCq" +
"pbo360gvdt05H5VZ/RDVkEgO2k73VSsbulqezKs8RFs2tEmU+JgTI9MeQJPWcP6X" +
"aKy6LIYs0E2cWgp8GADgoBs8llBq0UhX0KffglIeek3n7Z6Gt4YFge2TAcW2WbN4" +
"XfK7lupFyo6HHyWRiYHMMARQXLJeOSdTn5aMBP0PO4bQyk5ORxTUSeOciPJUFktQ" +
"HkvGbym7KryEfwH8Tks0L7WhzyP60PL3xS9FNOJi9m+zztwYIXGDQuKM2GDsITeD" +
"2mI2oHoPMyAD0wdI7BwSVW18p1h+jgfc4dlexKYRAoGBAOVfuiEiOchGghV5vn5N" +
"RDNscAFnpHj1QgMr6/UG05RTgmcLfVsI1I4bSkbrIuVKviGGf7atlkROALOG/xRx" +
"DLadgBEeNyHL5lz6ihQaFJLVQ0u3U4SB67J0YtVO3R6lXcIjBDHuY8SjYJ7Ci6Z6" +
"vuDcoaEujnlrtUhaMxvSfcUJAoGBAMPsCHXte1uWNAqYad2WdLjPDlKtQJK1diCm" +
"rqmB2g8QE99hDOHItjDBEdpyFBKOIP+NpVtM2KLhRajjcL9Ph8jrID6XUqikQuVi" +
"4J9FV2m42jXMuioTT13idAILanYg8D3idvy/3isDVkON0X3UAVKrgMEne0hJpkPL" +
"FYqgetvDAoGBAKLQ6JZMbSe0pPIJkSamQhsehgL5Rs51iX4m1z7+sYFAJfhvN3Q/" +
"OGIHDRp6HjMUcxHpHw7U+S1TETxePwKLnLKj6hw8jnX2/nZRgWHzgVcY+sPsReRx" +
"NJVf+Cfh6yOtznfX00p+JWOXdSY8glSSHJwRAMog+hFGW1AYdt7w80XBAoGBAImR" +
"NUugqapgaEA8TrFxkJmngXYaAqpA0iYRA7kv3S4QavPBUGtFJHBNULzitydkNtVZ" +
"3w6hgce0h9YThTo/nKc+OZDZbgfN9s7cQ75x0PQCAO4fx2P91Q+mDzDUVTeG30mE" +
"t2m3S0dGe47JiJxifV9P3wNBNrZGSIF3mrORBVNDAoGBAI0QKn2Iv7Sgo4T/XjND" +
"dl2kZTXqGAk8dOhpUiw/HdM3OGWbhHj2NdCzBliOmPyQtAr770GITWvbAI+IRYyF" +
"S7Fnk6ZVVVHsxjtaHy1uJGFlaZzKR4AGNaUTOJMs6NadzCmGPAxNQQOCqoUjn4XR" +
"rOjr9w349JooGXhOxbu8nOxX"
)
)
)
val signer = HttpMessageSignatureSigner()
val signatureBase = SignatureBaseBuilder()
.header("Host", "example.com")
.build()
val material = Material(
signatureBase,
key,
"sig"
)
val signatureParameter = SignatureParameter(
algorithm = "rsa-pss-sha512",
keyId = "a",
created = Instant.ofEpochSecond(1727076643),
// expires = Instant.ofEpochSecond(1727076943),
nonce = "a",
tag = "a"
)
val sign = signer.sign(
material,
signatureParameter,
RsaPssSha512SignatureSigner()
)
val expectedSignatureBase ="\"host\": example.com\n" +
"\"@signature-params\": (\"host\");alg=\"rsa-pss-sha512\";keyid=\"a\";created=1727076643;nonce=\"a\";tag=\"a\""
val expectedSignatureInput = "sig=(\"host\");alg=\"rsa-pss-sha512\";keyid=\"a\";created=1727076643;nonce=\"a\";tag=\"a\""
assertEquals(expectedSignatureBase, signatureBase.generateSignatureBase(signatureParameter))
assertEquals(expectedSignatureInput, sign.signatureInput)
println(sign.signature)
println(signatureBase.generateSignatureBase(signatureParameter))
val publicKey = KeyFactory.getInstance("RSA").generatePublic(
X509EncodedKeySpec(
Base64.getDecoder().decode(
"MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAr4tmm3r20Wd/PbqvP1s2" +
"+QEtvpuRaV8Yq40gjUR8y2Rjxa6dpG2GXHbPfvMs8ct+Lh1GH45x28Rw3Ry53mm+" +
"oAXjyQ86OnDkZ5N8lYbggD4O3w6M6pAvLkhk95AndTrifbIFPNU8PPMO7OyrFAHq" +
"gDsznjPFmTOtCEcN2Z1FpWgchwuYLPL+Wokqltd11nqqzi+bJ9cvSKADYdUAAN5W" +
"Utzdpiy6LbTgSxP7ociU4Tn0g5I6aDZJ7A8Lzo0KSyZYoA485mqcO0GVAdVw9lq4" +
"aOT9v6d+nb4bnNkQVklLQ3fVAvJm+xdDOp9LCNCN48V2pnDOkFV6+U9nV5oyc6XI" +
"2wIDAQAB"
)
)
)
val signature = Signature.getInstance("RSASSA-PSS")
signature.setParameter(PSSParameterSpec("SHA-512", "MGF1", MGF1ParameterSpec.SHA512, 64, PSSParameterSpec.TRAILER_FIELD_BC))
signature.initVerify(publicKey)
signature.update(signatureBase.generateSignatureBase(signatureParameter).toByteArray())
val verify = signature.verify(Base64.getDecoder().decode(sign.signature))
assertTrue(verify)
}
}