我正在实现 OpenID Connect 代码流,并且在使用 javax.crypto.Mac 生成 HMACSHA-256 签名时如何使用客户端密码作为密钥有点困惑。我不知道如何将客户端 ID 转换为关键字节。
import org.apache.commons.codec.Charsets;
import org.apache.commons.codec.binary.Base64;
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
public class HMACSigner {
public static final String HMACSHA256 = "HmacSHA256";
public String createSignature(final String messageToSign, final String clientSecret) {
// How do I convert the client secret to the key byte array?
SecretKeySpec secretKey = new SecretKeySpec(clientSecret.getBytes(Charsets.UTF_8), HMACSHA256);
try {
Mac mac = Mac.getInstance(HMACSHA256);
mac.init(secretKey);
byte[] bytesToSign = messageToSign.getBytes(Charsets.US_ASCII);
byte[] signature = mac.doFinal(bytesToSign);
return Base64.encodeBase64URLSafeString(signature);
}
catch (NoSuchAlgorithmException e) {
throw new RuntimeException(e);
}
catch (InvalidKeyException e) {
throw new RuntimeException(e);
}
}
}
按照https://datatracker.ietf.org/doc/html/draft-ietf-jose-json-web-signature-17#appendix-A中的示例,我创建了以下测试用例。我的输出是ZekyXWlxvuCN9H8cuDrZfaRa3pMJhHpv6QKFdUqXbLc
.
import org.junit.Test;
import static org.junit.Assert.assertEquals;
public class HMACSignerTest {
private HMACSigner sut;
@Test
public void should_create_signature_according_to_spec() {
sut = new HMACSigner();
String signature = sut.createSignature("eyJ0eXAiOiJKV1QiLA0KICJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJqb2UiLA0KICJleHAiOjEzMDA4MTkzODAsDQogImh0dHA6Ly9leGFtcGxlLmNvbS9pc19yb290Ijp0cnVlfQ",
"AyM1SysPpbyDfgZld3umj1qzKObwVMkoqQ-EstJQLr_T-1qS0gZH75aKtMN3Yj0iPS4hcgUuTwjAzZr1Z9CAow");
assertEquals("dBjftJeZ4CVP-mB92K27uhbUJU1p1r_wW1gFWFOEjXk", signature);
}
}