1 /* 2 * Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. 8 * 9 * This code is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 * version 2 for more details (a copy is included in the LICENSE file that 13 * accompanied this code). 14 * 15 * You should have received a copy of the GNU General Public License version 16 * 2 along with this work; if not, write to the Free Software Foundation, 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 */ 23 24 /** 25 * @see SignUsingNONEwithRSA.sh 26 */ 27 28 import java.security.*; 29 import java.util.*; 30 31 public class SignUsingNONEwithRSA { 32 33 private static final List<byte[]> precomputedHashes = Arrays.asList( 34 // A MD5 hash 35 new byte[] { 36 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x10, 37 0x11, 0x12, 0x13, 0x14, 0x15, 0x16 38 }, 39 // A SHA-1 hash 40 new byte[] { 41 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x10, 42 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x20 43 }, 44 // A concatenation of SHA-1 and MD5 hashes (used during SSL handshake) 45 new byte[] { 46 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x10, 47 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x20, 48 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x30, 49 0x31, 0x32, 0x33, 0x34, 0x35, 0x36 50 }, 51 // A SHA-224 hash 52 new byte[] { 53 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x10, 54 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x20, 55 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28 56 }, 57 // A SHA-256 hash 58 new byte[] { 59 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x10, 60 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x20, 61 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x30, 62 0x31, 0x32 63 }, 64 // A SHA-384 hash 65 new byte[] { 66 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x10, 67 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x20, 68 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x30, 69 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x40, 70 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48 71 }, 72 // A SHA-512 hash 73 new byte[] { 74 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x10, 75 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x20, 76 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x30, 77 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x40, 78 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x50, 79 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x60, 80 0x61, 0x62, 0x63, 0x64 81 }); 82 83 private static List<byte[]> generatedSignatures = new ArrayList<>(); 84 85 public static void main(String[] args) throws Exception { 86 87 Provider[] providers = Security.getProviders("Signature.NONEwithRSA"); 88 if (providers == null) { 89 System.out.println("No JCE providers support the " + 90 "'Signature.NONEwithRSA' algorithm"); 91 System.out.println("Skipping this test..."); 92 return; 93 94 } else { 95 System.out.println("The following JCE providers support the " + 96 "'Signature.NONEwithRSA' algorithm: "); 97 for (Provider provider : providers) { 98 System.out.println(" " + provider.getName()); 99 } 100 } 101 System.out.println("-------------------------------------------------"); 102 103 KeyPair keys = getKeysFromKeyStore(); 104 signAllUsing("SunMSCAPI", keys.getPrivate()); 105 System.out.println("-------------------------------------------------"); 106 107 verifyAllUsing("SunMSCAPI", keys.getPublic()); 108 System.out.println("-------------------------------------------------"); 109 110 verifyAllUsing("SunJCE", keys.getPublic()); 111 System.out.println("-------------------------------------------------"); 112 113 keys = generateKeys(); 114 signAllUsing("SunJCE", keys.getPrivate()); 115 System.out.println("-------------------------------------------------"); 116 117 verifyAllUsing("SunMSCAPI", keys.getPublic()); 118 System.out.println("-------------------------------------------------"); 119 120 } 121 122 private static KeyPair getKeysFromKeyStore() throws Exception { 123 KeyStore ks = KeyStore.getInstance("Windows-MY", "SunMSCAPI"); 124 ks.load(null, null); 125 System.out.println("Loaded keystore: Windows-MY"); 126 127 Enumeration e = ks.aliases(); 128 PrivateKey privateKey = null; 129 PublicKey publicKey = null; 130 131 while (e.hasMoreElements()) { 132 String alias = (String) e.nextElement(); 133 if (alias.equals("6578658")) { 134 System.out.println("Loaded entry: " + alias); 135 privateKey = (PrivateKey) ks.getKey(alias, null); 136 publicKey = (PublicKey) ks.getCertificate(alias).getPublicKey(); 137 } 138 } 139 if (privateKey == null || publicKey == null) { 140 throw new Exception("Cannot load the keys need to run this test"); 141 } 142 143 return new KeyPair(publicKey, privateKey); 144 } 145 146 147 private static KeyPair generateKeys() throws Exception { 148 KeyPairGenerator keyGen = KeyPairGenerator.getInstance("RSA"); 149 keyGen.initialize(1024, null); 150 KeyPair pair = keyGen.generateKeyPair(); 151 PrivateKey privateKey = pair.getPrivate(); 152 PublicKey publicKey = pair.getPublic(); 153 154 if (privateKey == null || publicKey == null) { 155 throw new Exception("Cannot load the keys need to run this test"); 156 } 157 158 return new KeyPair(publicKey, privateKey); 159 } 160 161 private static void signAllUsing(String providerName, PrivateKey privateKey) 162 throws Exception { 163 Signature sig1 = Signature.getInstance("NONEwithRSA", providerName); 164 if (sig1 == null) { 165 throw new Exception("'NONEwithRSA' is not supported"); 166 } 167 if (sig1.getProvider() != null) { 168 System.out.println("Using NONEwithRSA signer from the " + 169 sig1.getProvider().getName() + " JCE provider"); 170 } else { 171 System.out.println( 172 "Using NONEwithRSA signer from the internal JCE provider"); 173 } 174 175 System.out.println("Using key: " + privateKey); 176 generatedSignatures.clear(); 177 for (byte[] hash : precomputedHashes) { 178 sig1.initSign(privateKey); 179 sig1.update(hash); 180 181 try { 182 183 byte [] sigBytes = sig1.sign(); 184 System.out.println("\nGenerated RSA signature over a " + 185 hash.length + "-byte hash (signature length: " + 186 sigBytes.length * 8 + " bits)"); 187 System.out.println(String.format("0x%0" + 188 (sigBytes.length * 2) + "x", 189 new java.math.BigInteger(1, sigBytes))); 190 generatedSignatures.add(sigBytes); 191 192 } catch (SignatureException se) { 193 System.out.println("Error generating RSA signature: " + se); 194 } 195 } 196 } 197 198 private static void verifyAllUsing(String providerName, PublicKey publicKey) 199 throws Exception { 200 Signature sig1 = Signature.getInstance("NONEwithRSA", providerName); 201 if (sig1.getProvider() != null) { 202 System.out.println("\nUsing NONEwithRSA verifier from the " + 203 sig1.getProvider().getName() + " JCE provider"); 204 } else { 205 System.out.println( 206 "\nUsing NONEwithRSA verifier from the internal JCE provider"); 207 } 208 209 System.out.println("Using key: " + publicKey); 210 211 int i = 0; 212 for (byte[] hash : precomputedHashes) { 213 214 byte[] sigBytes = generatedSignatures.get(i++); 215 System.out.println("\nVerifying RSA Signature over a " + 216 hash.length + "-byte hash (signature length: " + 217 sigBytes.length * 8 + " bits)"); 218 System.out.println(String.format("0x%0" + 219 (sigBytes.length * 2) + "x", 220 new java.math.BigInteger(1, sigBytes))); 221 222 sig1.initVerify(publicKey); 223 sig1.update(hash); 224 if (sig1.verify(sigBytes)) { 225 System.out.println("Verify PASSED"); 226 } else { 227 throw new Exception("Verify FAILED"); 228 } 229 } 230 } 231 }