1

我正在实现 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);
    }

}
4

1 回答 1

1

密钥似乎是 Base64 编码的:

SecretKeySpec secretKey = new SecretKeySpec(Base64.decodeBase64(clientSecret), HMACSHA256);
于 2013-11-06T10:49:54.343 回答