/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.tomitribe.auth.signatures; import org.junit.Assert; import org.junit.Test; import java.io.ByteArrayInputStream; import java.security.PrivateKey; import java.security.PublicKey; import java.util.Arrays; import java.util.HashMap; import java.util.Map; import java.security.spec.AlgorithmParameterSpec; import java.security.spec.PSSParameterSpec; import java.security.spec.MGF1ParameterSpec; public class RsaTest extends Assert { private final String privateKeyPem = "-----BEGIN RSA PRIVATE KEY-----\n" + "MIICXgIBAAKBgQDCFENGw33yGihy92pDjZQhl0C36rPJj+CvfSC8+q28hxA161QF\n" + "NUd13wuCTUcq0Qd2qsBe/2hFyc2DCJJg0h1L78+6Z4UMR7EOcpfdUE9Hf3m/hs+F\n" + "UR45uBJeDK1HSFHD8bHKD6kv8FPGfJTotc+2xjJwoYi+1hqp1fIekaxsyQIDAQAB\n" + "AoGBAJR8ZkCUvx5kzv+utdl7T5MnordT1TvoXXJGXK7ZZ+UuvMNUCdN2QPc4sBiA\n" + "QWvLw1cSKt5DsKZ8UETpYPy8pPYnnDEz2dDYiaew9+xEpubyeW2oH4Zx71wqBtOK\n" + "kqwrXa/pzdpiucRRjk6vE6YY7EBBs/g7uanVpGibOVAEsqH1AkEA7DkjVH28WDUg\n" + "f1nqvfn2Kj6CT7nIcE3jGJsZZ7zlZmBmHFDONMLUrXR/Zm3pR5m0tCmBqa5RK95u\n" + "412jt1dPIwJBANJT3v8pnkth48bQo/fKel6uEYyboRtA5/uHuHkZ6FQF7OUkGogc\n" + "mSJluOdc5t6hI1VsLn0QZEjQZMEOWr+wKSMCQQCC4kXJEsHAve77oP6HtG/IiEn7\n" + "kpyUXRNvFsDE0czpJJBvL/aRFUJxuRK91jhjC68sA7NsKMGg5OXb5I5Jj36xAkEA\n" + "gIT7aFOYBFwGgQAQkWNKLvySgKbAZRTeLBacpHMuQdl1DfdntvAyqpAZ0lY0RKmW\n" + "G6aFKaqQfOXKCyWoUiVknQJAXrlgySFci/2ueKlIE1QqIiLSZ8V8OlpFLRnb1pzI\n" + "7U1yQXnTAEFYM560yJlzUpOb1V4cScGd365tiSMvxLOvTA==\n" + "-----END RSA PRIVATE KEY-----\n"; private final String publicKeyPem = "-----BEGIN PUBLIC KEY-----\n" + "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDCFENGw33yGihy92pDjZQhl0C3\n" + "6rPJj+CvfSC8+q28hxA161QFNUd13wuCTUcq0Qd2qsBe/2hFyc2DCJJg0h1L78+6\n" + "Z4UMR7EOcpfdUE9Hf3m/hs+FUR45uBJeDK1HSFHD8bHKD6kv8FPGfJTotc+2xjJw\n" + "oYi+1hqp1fIekaxsyQIDAQAB\n" + "-----END PUBLIC KEY-----\n"; private final PrivateKey privateKey; private final PublicKey publicKey; private final String method = "POST"; private final String uri = "/foo?param=value&pet=dog"; private final Map<String, String> headers = new HashMap<String, String>(); { headers.put("Host", "example.org"); headers.put("Date", "Thu, 05 Jan 2012 21:31:40 GMT"); headers.put("Content-Type", "application/json"); headers.put("Digest", "SHA-256=X48E9qOokqqrvdts8nOJRJN3OWDUoyWxBf7kbu9DBPE="); headers.put("Accept", "*/*"); headers.put("Content-Length", "18"); } public RsaTest() throws Exception { privateKey = PEM.readPrivateKey(new ByteArrayInputStream(privateKeyPem.getBytes())); publicKey = PEM.readPublicKey(new ByteArrayInputStream(publicKeyPem.getBytes())); } @Test public void rsaSha1() throws Exception { final Algorithm algorithm = Algorithm.RSA_SHA1; assertSignature(algorithm, "kcX/cWMRQEjUPfF6AO7ANZ/eQkpRd" + "/4+dr3g1B5HZBn3vRDxGFbDRY19HeJUUlBAgmvolRwLlrVkz" + "LOmYdug6Ff01UUl6gX+TksGbsxagbNUNoEx0hrX3+8Jbd+x8" + "gx9gZxA7DwXww1u3bGrmChnfkdOofY52KhUllUox4mmBeI=", "date"); assertSignature(algorithm, "F6g4qdBSHBcWo1iMsHetQU9TnPF39" + "naVHQogAhgvY6wh0/cdkquN4D6CInTyEHtMuv7xlOt0yBaVt" + "brrNP5JZKquYMW2JC3FXdtIiaYWhLUb/Nmb+JPr6C8AnxMzc" + "fNfuOZFn3X7ekA32qbfnYr7loHqpEGUr+G1NYsckEXdlM4=", "(request-target)", "host", "date"); } @Test public void rsaSha256() throws Exception { final Algorithm algorithm = Algorithm.RSA_SHA256; assertSignature(algorithm, "ATp0r26dbMIxOopqw0OfABDT7CKMI" + "oENumuruOtarj8n/97Q3htHFYpH8yOSQk3Z5zh8UxUym6FYT" + "b5+A0Nz3NRsXJibnYi7brE/4tx5But9kkFGzG+xpUmimN4c3" + "TMN7OFH//+r8hBf7BT9/GmHDUVZT2JzWGLZES2xDOUuMtA=", "date"); assertSignature(algorithm, "DT9vcDFbit2ahGZowjUzzih+sVpKM" + "IPZrXy1DMljImYNSJ3UEweTMfF3MUFjdNwYH59IDJoB+QTg3" + "Rpm5xLvMWD7tql/Ng/NCJs8gYSNjOQidArEpWp88c5IQPDXn" + "1lnJMU6dNXZNxc8Yqj+mIYhwHpKEKTqnvEtnCvB/6y/dIM=", "(request-target)", "host", "date"); } @Test public void rsaSha384() throws Exception { final Algorithm algorithm = Algorithm.RSA_SHA384; assertSignature(algorithm, "AYtR6NQy+59Ta3X1GYNlfOzJo4Sg+" + "aB+ulDkR6Q2/8egvByRx5l0+t/2abAaFHf33SDojHYWPlpuj" + "HM26ExZPFXeYzG9sRctKD7XKrA/F6LRXEm1RXLFvfvLXQw4P" + "4HE1PMH+gCw2E+6IoTnbcimQtZ82SkF1uDRtLDhR6iqpFI=" , "date"); assertSignature(algorithm, "mRaP0Z5lh9XKGDahdsomoKR9Kjsj9" + "a/lgUEpZDQpvSZq5NhODEjmQh1qRn6Sx/c+AFl67yzDYAMXx" + "9h49ZOpKpuj4FGrz5/DIK7cdn9wXBKqDYgDfwOF9O5jNOE1r" + "9zbORTH0XxA8WE9H/MXoOrDIH1NjM5o9I4ErT4zKnD5OsQ=" , "(request-target)", "host", "date"); } @Test public void rsaSha512() throws Exception { final Algorithm algorithm = Algorithm.RSA_SHA512; assertSignature(algorithm, "IItboA8OJgL8WSAnJa8MND04s9j7d" + "B6IJIBVpOGJph8Tmkc5yUAYjvO/UQUKytRBe5CSv2GLfTAmE" + "7SuRgGGMwdQZubNJqRCiVPKBpuA47lXrKgC/wB0QAMkPHI6c" + "PllBZRixmjZuU9mIbuLjXMHR+v/DZwOHT9k8x0ILUq2rKE=" , "date"); assertSignature(algorithm, "ggIa4bcI7q377gNoQ7qVYxTA4pEOl" + "xlFzRtiQV0SdPam4sK58SFO9EtzE0P1zVTymTnsSRChmFU2p" + "n+R9VzkAhQ+yEbTqzu+mgHc4P1L5IeeXQ5aAmGENfkRbm2vd" + "OZzP5j6ruB+SJXIlhnaum2lsuyytSS0m/GkWvFJVZFu33M=" , "(request-target)", "host", "date"); } @Test public void rsaSsaPss() throws Exception { final Algorithm algorithm = Algorithm.RSA_PSS; final AlgorithmParameterSpec spec = new PSSParameterSpec("SHA-256", "MGF1", MGF1ParameterSpec.SHA256, 32, 1); final Signer signer = new Signer(privateKey, new Signature("some-key-1", SigningAlgorithm.HS2019, algorithm, spec, null, Arrays.asList("date"))); final Signature signature = signer.sign(method, uri, headers); // The RSASSA-PSS signature is non-deterministic, the value of the signature will be different // every time a signature is generated. final Verifier verifier = new Verifier(publicKey, signature); boolean verifies = verifier.verify(method, uri, headers); assertTrue(verifies); } private void assertSignature(final Algorithm algorithm, final String expected, final String... sign) throws Exception { final Signer signer = new Signer(privateKey, new Signature("some-key-1", SigningAlgorithm.HS2019, algorithm, null, null, Arrays.asList(sign))); final Signature signed = signer.sign(method, uri, headers); assertEquals(expected, signed.getSignature()); } }