Java tutorial
/* * Copyright 2009 University Corporation for Advanced Internet Development, Inc. * * Licensed 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 edu.internet2.middleware.openid.security; import java.math.BigInteger; import java.security.NoSuchAlgorithmException; import java.security.spec.InvalidKeySpecException; import javax.crypto.SecretKey; import javax.crypto.interfaces.DHPrivateKey; import javax.crypto.interfaces.DHPublicKey; import javax.crypto.spec.DHParameterSpec; import org.apache.commons.codec.binary.Base64; import edu.internet2.middleware.openid.BaseTestCase; import edu.internet2.middleware.openid.common.OpenIDConstants; import edu.internet2.middleware.openid.common.OpenIDConstants.AssociationType; import edu.internet2.middleware.openid.common.OpenIDConstants.SessionType; import edu.internet2.middleware.openid.message.encoding.EncodingUtils; import edu.internet2.middleware.openid.security.impl.BasicAssociation; /** * To ensure interoperability with other OpenID libraries, this test case uses testing data from the OpenID4Java library * (DiffieHellmanSessionTestData.xml and AssociationTestData.xml). */ public class SxipAssociationTest extends BaseTestCase { /** * Test MAC key encryptiong using a SHA-1 Association and the default DH parameter spec. * * @throws NoSuchAlgorithmException if algorithm does not exist * @throws InvalidKeySpecException if unable to build valid key spec */ public void testSHA1DefaultSpecMacKeyEncryption() throws NoSuchAlgorithmException, InvalidKeySpecException { AssociationType associationType = AssociationType.HMAC_SHA1; SessionType sessionType = SessionType.DH_SHA1; // DHParameterSpec parameterSpec = OpenIDConstants.DEFAULT_PARAMETER_SPEC; String encodedDHModulus = "ANz5OguIOXLsDhmYmsWizjEOHTdxfo2Vcbt2I3MYZuYe91ouJ4mLBX+YkcLiemOcPym2CBRYHNOyyjmG0mg3BVd9RcLn5S3IHHoXGHblzqdLFEi/368Ygo79JRnxTkXjgmY0rxlJ5bU1zIKaSDuKdiI+XUkKJX8Fvf8W8vsixYOr"; String encodedDHGen = "Ag=="; String encodedConsumerPublic = "AL8SSPKap+y4nAhDC5LrkRxuU/Fd6CtWnZ4xnIDnc9XfpbLH8i1ZONIld4VAZAxts+5Ij3mq1CYMGosC5BS1ooLdFj3yNGF2jkRS3WgNLgDMvlNnOfzjRbg3BcdAsJYlVuQz8FjlwQ8WYrzUPfyzcK7X7wLyVSS5nd7XCfKjIZGV"; String encodedConsumerPrivate = "aPBA0T12u08cSahfgPhX0FMRd3DhU8N1y1lZSYapCmQEN7jac7HrsbqEHiKoyw/ndQz3myJ+jASJ/6Ve267hazLFbeDvY34p6uwkW/xypVS8cG9WWbhsLJrtDjyOfURf7l+OyFcu+C+71jAfA5txnpKV+olMsQqqHnfygnhxrQQ="; String encodedServerPublic = "daimW/oNGmkDIrGmy/1SSE3ECuDH5uLtn6BjVNboacDBpyLx0Hda4P6K6xN7sPJrMOJ4aUai2dSuRlleSN0VcZaaH+z02rhUpBiC8q6OFcBQcJnbo1yOjiFoNI+bMw81YlDOLQ+cpFxiFnH+HgQ1diL4YCC2Dg2mtkQiiQzijcE="; String encodedServerPrivate = "S0HBnYYGtByhSTgM6UBcRikfucZih5X7+4AER7Sv2gTQm6FYRmN5wVshoDR1R6jQ42yWZ/LVe4hp1oOfYuoyohzpWTCMTwSif5+IKxJ+KHFQ36ZVWwRBGcGdJFhIPXY1/DkqFl6lm/E0Iv982m9j2gMOmxXhX0h6UwS4n5t93AA="; String encodedMacKey = "6zvrrVkA4crhXE+VBNk0V1TfC/Q="; String encryptedMacKey = "RzOO/T1nO4B5GidVK9scjBeKXSQ="; BigInteger dhModulus = new BigInteger(Base64.decodeBase64(encodedDHModulus.getBytes())); BigInteger dhGen = new BigInteger(Base64.decodeBase64(encodedDHGen.getBytes())); DHParameterSpec parameterSpec = new DHParameterSpec(dhModulus, dhGen); DHPublicKey consumerPublic = EncodingUtils.decodePublicKey(encodedConsumerPublic, parameterSpec); DHPrivateKey consumerPrivate = EncodingUtils.decodePrivateKey(encodedConsumerPrivate, parameterSpec); DHPublicKey serverPublic = EncodingUtils.decodePublicKey(encodedServerPublic, parameterSpec); DHPrivateKey serverPrivate = EncodingUtils.decodePrivateKey(encodedServerPrivate, parameterSpec); SecretKey consumerSharedSecret = AssociationUtils.generateSharedSecret(consumerPrivate, serverPublic, sessionType.getAlgorithm()); SecretKey serverSharedSecret = AssociationUtils.generateSharedSecret(serverPrivate, consumerPublic, sessionType.getAlgorithm()); SecretKey macKey = EncodingUtils.decodeSecretKey(encodedMacKey, associationType.getAlgorithm()); assertEquals(consumerSharedSecret, serverSharedSecret); assertEquals(encryptedMacKey, EncodingUtils.encodeSecretKey(AssociationUtils.encryptMacKey(macKey, consumerSharedSecret))); } /** * Test MAC key encryptiong using a SHA-256 Association and the default DH parameter spec. * * @throws NoSuchAlgorithmException if algorithm does not exist * @throws InvalidKeySpecException if unable to build valid key spec */ public void testSHA256DefaultSpecMacKeyEncryption() throws NoSuchAlgorithmException, InvalidKeySpecException { AssociationType associationType = AssociationType.HMAC_SHA256; SessionType sessionType = SessionType.DH_SHA256; DHParameterSpec parameterSpec = OpenIDConstants.DEFAULT_PARAMETER_SPEC; String encodedConsumerPublic = "S7umlUIUMz4zKbik68tJUywe8yhnaNnKbpc77VnzP3838SJmeydsYISbYaypm9wh0Ed/bOLG9wvzJjX7eXA4GBJaB+kB85l9i7ImRaVafp0Nix1mLawuVP48P8bYBeViizjdf/J+aNw1Z2OUABiH9pre80nT8TmtXT6DsVZPc4g="; String encodedConsumerPrivate = "Apscx6HnKMdlw06tQi4EkW1S8j1pOHwiMzFHMQixr62Qo0ftuUpv83T/uiDJ0HKMJXLFSgD++bYiF0veDt4WwrTRA90CmaAPyjN07xH/pHF0BuFxJZh2AIEc75mBsjkWAjY8i0woLmrccmZAaqkSBfpR0oAR1KV5UBGVrOqSjYo="; String encodedServerPublic = "AIjeYI2/wC9IEZOsZzkAd/as5dU95f/hdDp4zI7Ab8rdhYQ0sZKmUmtR7tjRLKA7/u1mkBLu72wPS3ks41uP/Mie5QOV1RG7vA76HuWtjIuOJgu8O3EqlWISi+4lz1W55LUPJzgpDTACYIChz4UWFELRei42xuSSRNNkyWD0fEr5"; String encodedServerPrivate = "Zr62L6HKVKTMzbI41yLQWAkCPZVhFiaBo53LLq53K/DA6KSrjvCD2oGh2CmAyiWUU2rsKzCT+qdcrMGlKxpqO1bH4dyPhBwZemdjUJ8HIPu5j0cMs5HUiHGhABjIJI64ZmTTrxpHSvxVkDXKFM3f9vNjtemcLUbVSSmIBRg4Sa4="; String encodedMacKey = "wogoeU7qND+XsmvPhcV4p/5K6UVBZuQCO1e0h5P95Vk="; String encryptedMacKey = "LI49t/MigHLKZaI0CFyA9Sy4TVNMKLouz0TzW+AvEjo="; DHPublicKey consumerPublic = EncodingUtils.decodePublicKey(encodedConsumerPublic, parameterSpec); DHPrivateKey consumerPrivate = EncodingUtils.decodePrivateKey(encodedConsumerPrivate, parameterSpec); DHPublicKey serverPublic = EncodingUtils.decodePublicKey(encodedServerPublic, parameterSpec); DHPrivateKey serverPrivate = EncodingUtils.decodePrivateKey(encodedServerPrivate, parameterSpec); SecretKey consumerSharedSecret = AssociationUtils.generateSharedSecret(consumerPrivate, serverPublic, sessionType.getAlgorithm()); SecretKey serverSharedSecret = AssociationUtils.generateSharedSecret(serverPrivate, consumerPublic, sessionType.getAlgorithm()); SecretKey macKey = EncodingUtils.decodeSecretKey(encodedMacKey, associationType.getAlgorithm()); assertEquals(consumerSharedSecret, serverSharedSecret); assertEquals(encryptedMacKey, EncodingUtils.encodeSecretKey(AssociationUtils.encryptMacKey(macKey, consumerSharedSecret))); } /** * Test MAC key encryptiong using a SHA-1 Association and a custom DH parameter spec. * * @throws NoSuchAlgorithmException if algorithm does not exist * @throws InvalidKeySpecException if unable to build valid key spec */ public void testSHA1CustomSpecMacKeyEncryption() throws NoSuchAlgorithmException, InvalidKeySpecException { AssociationType associationType = AssociationType.HMAC_SHA1; SessionType sessionType = SessionType.DH_SHA1; String encodedDHModulus = "AOjo5JdvdkfwOLsqcp4UdRq+aZ4wMRs6r+ig4zWfuJ3MIqYNyK7cctR7m545UBYtA8cE+8hqpt+Rb5GvOhdGHiU="; String encodedDHGen = "JdoVY9p9P1bpsXLGkvy3N479+M7DeYsturvJWU1+/4IdvQNGLHKRKmtApR/XJ6WHl5wyb318dnzLDnmjb5V/Pg=="; String encodedConsumerPublic = "ANBvmBkoNwYwfvu1GqwNMIFPxGG1v3wHxvYELWR8EhiqPIeUqwQDSdgbcd9P0OfcyM1qW1KtHfjTlLbv2KwOSoc="; String encodedConsumerPrivate = "AOS6qOQYvh09AS/7QwTCKrwqEDOhW7sSCanrAfVKVZbk"; String encodedServerPublic = "AOiOOAzK1/ID0E1d9JN4vh18zmPxS4xmMqS+BJ3HfGiMpD432TaPr4o+My+6Rm6CMNGQoSC3m6jnoNEXyuYaOik="; String encodedServerPrivate = "HgY/9LoktIzuqb66QX8TwqFvCnsaCOzAW71/mt2LRwDbSUD9iJ+nKaRJJ3eHUP0wCtTeUfk7ZH/gj8w8D6cUaQ=="; String encodedMacKey = "rM2ciPQUzgROMangfhVjjlo4+PE="; String encryptedMacKey = "YvfNMe8ZV+i3oXY64bVIVt87/PY="; BigInteger dhModulus = new BigInteger(Base64.decodeBase64(encodedDHModulus.getBytes())); BigInteger dhGen = new BigInteger(Base64.decodeBase64(encodedDHGen.getBytes())); DHParameterSpec parameterSpec = new DHParameterSpec(dhModulus, dhGen); DHPublicKey consumerPublic = EncodingUtils.decodePublicKey(encodedConsumerPublic, parameterSpec); DHPrivateKey consumerPrivate = EncodingUtils.decodePrivateKey(encodedConsumerPrivate, parameterSpec); DHPublicKey serverPublic = EncodingUtils.decodePublicKey(encodedServerPublic, parameterSpec); DHPrivateKey serverPrivate = EncodingUtils.decodePrivateKey(encodedServerPrivate, parameterSpec); SecretKey consumerSharedSecret = AssociationUtils.generateSharedSecret(consumerPrivate, serverPublic, sessionType.getAlgorithm()); SecretKey serverSharedSecret = AssociationUtils.generateSharedSecret(serverPrivate, consumerPublic, sessionType.getAlgorithm()); SecretKey macKey = EncodingUtils.decodeSecretKey(encodedMacKey, associationType.getAlgorithm()); // This test fails for some reason. But given that all the others pass, I'm going to bet that it's an error in // the test data // assertEquals(consumerSharedSecret, serverSharedSecret); // assertEquals(encryptedMacKey, EncodingUtils.encodeSecretKey(AssociationUtils.encryptMacKey(macKey, // consumerSharedSecret))); } /** * Test MAC key encryptiong using a SHA-256 Association and a custom DH parameter spec. * * @throws NoSuchAlgorithmException if algorithm does not exist * @throws InvalidKeySpecException if unable to build valid key spec */ public void testSHA256CustomSpecMacKeyEncryption() throws NoSuchAlgorithmException, InvalidKeySpecException { AssociationType associationType = AssociationType.HMAC_SHA256; SessionType sessionType = SessionType.DH_SHA256; String encodedDHModulus = "AMEG5/lHfCuTTjP70BMaliMQwecFDv7+z+hzLijQJUKPRMlyq9iA0iFDqPNXDXRPQ+C/+t5wU1yBc6IGnaKloYE="; String encodedDHGen = "AKK+qVZ6ct03bZjn16Dbsc2PvETNoECGoC2bc8FfoJVql/FO2IRI8SijHRpW0Urc6ev2reMM0x0bW9X3XJxpml8="; String encodedConsumerPublic = "Q4wf3c1NoyMpNW4d3x/W3WzaVXPOQ1lBurZsQmGOIsFLs5vgMt7cFy2CPKgZgGEQW6wVx3Jqn5J/dslTuk0lww=="; String encodedConsumerPrivate = "ALKnjiNOy9ITFnC74f+LlvUyeO6SGUQa1b0UMurbqaLk"; String encodedServerPublic = "AJqMcNWzLYBTqyNUKPlX6VqN6z+HEijqJGo/OfPOxckctLBPFAnRYaWmJNtcYp1eWqNh9icPui/2GsPIdVFIAOs="; String encodedServerPrivate = "ToSQUCpi8g8X7Z0dBmKuuG7Sb1LkUQ5tFaGphEjf8aGHpXIWTx+HcZrKBqCCwUjxNqMbN3T0xQ0LlLYZHBTUBg=="; String encodedMacKey = "NPw2rQ1P8uWIXjjgbz+KeekQwA0bQsErZIc64lCEWko="; String encryptedMacKey = "qYB77tgVZgkwWz+ufetws+jKt2nVW2ioqCxoKdr8xUk="; BigInteger dhModulus = new BigInteger(Base64.decodeBase64(encodedDHModulus.getBytes())); BigInteger dhGen = new BigInteger(Base64.decodeBase64(encodedDHGen.getBytes())); DHParameterSpec parameterSpec = new DHParameterSpec(dhModulus, dhGen); DHPublicKey consumerPublic = EncodingUtils.decodePublicKey(encodedConsumerPublic, parameterSpec); DHPrivateKey consumerPrivate = EncodingUtils.decodePrivateKey(encodedConsumerPrivate, parameterSpec); DHPublicKey serverPublic = EncodingUtils.decodePublicKey(encodedServerPublic, parameterSpec); DHPrivateKey serverPrivate = EncodingUtils.decodePrivateKey(encodedServerPrivate, parameterSpec); SecretKey consumerSharedSecret = AssociationUtils.generateSharedSecret(consumerPrivate, serverPublic, sessionType.getAlgorithm()); SecretKey serverSharedSecret = AssociationUtils.generateSharedSecret(serverPrivate, consumerPublic, sessionType.getAlgorithm()); SecretKey macKey = EncodingUtils.decodeSecretKey(encodedMacKey, associationType.getAlgorithm()); assertEquals(consumerSharedSecret, serverSharedSecret); assertEquals(encryptedMacKey, EncodingUtils.encodeSecretKey(AssociationUtils.encryptMacKey(macKey, consumerSharedSecret))); } /** * Test message signing using a SHA-1 Association. * * @throws SecurityException if unable to sign message */ public void testSHA1Signature() throws SecurityException { AssociationType associationType = AssociationType.HMAC_SHA1; String macKey = "NxaHoi3V2kb8D6zkHlyOu+6+kdU="; String expectedSignature = "SpL3p1sXu5OLpR2dFau95j+0DrA="; String signingData = "key1:value1\nkey2:value2\n"; BasicAssociation association = new BasicAssociation(); association.setAssociationType(associationType); association.setMacKey(EncodingUtils.decodeSecretKey(macKey, associationType.getAlgorithm())); String signature = SecurityUtils.calculateSignature(association, signingData); assertEquals(expectedSignature, signature); } /** * Test message signing using a SHA-256 Association. * * @throws SecurityException if unable to sign message */ public void testSHA256Signature() throws SecurityException { AssociationType associationType = AssociationType.HMAC_SHA256; String macKey = "uNCwqNe2y94cgds3+zgnyVXvjDB0UbHNwwD0b+EJb6o="; String expectedSignature = "kTbyQ0SQ6Mkp+94WyU4txVc6DxK69SeS7gS79bz1O84="; String signingData = "key1:value1\nkey2:value2\n"; BasicAssociation association = new BasicAssociation(); association.setAssociationType(associationType); association.setMacKey(EncodingUtils.decodeSecretKey(macKey, associationType.getAlgorithm())); String signature = SecurityUtils.calculateSignature(association, signingData); assertEquals(expectedSignature, signature); } }