001package com.hfg.security; 002 003import java.io.*; 004import java.security.*; 005import java.security.spec.X509EncodedKeySpec; 006import java.security.spec.PKCS8EncodedKeySpec; 007 008 009//------------------------------------------------------------------------------ 010/** 011 * DSA-related functions. 012 * 013 * @author J. Alex Taylor, hairyfatguy.com 014 */ 015//------------------------------------------------------------------------------ 016// com.hfg XML/HTML Coding Library 017// 018// This library is free software; you can redistribute it and/or 019// modify it under the terms of the GNU Lesser General Public 020// License as published by the Free Software Foundation; either 021// version 2.1 of the License, or (at your option) any later version. 022// 023// This library is distributed in the hope that it will be useful, 024// but WITHOUT ANY WARRANTY; without even the implied warranty of 025// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 026// Lesser General Public License for more details. 027// 028// You should have received a copy of the GNU Lesser General Public 029// License along with this library; if not, write to the Free Software 030// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 031// 032// J. Alex Taylor, President, Founder, CEO, COO, CFO, OOPS hairyfatguy.com 033// jataylor@hairyfatguy.com 034//------------------------------------------------------------------------------ 035 036public class DSAUtil 037{ 038 //-------------------------------------------------------------------------- 039 public static void generateDSAKeyPair(File inOutputDir) 040 { 041 try 042 { 043 KeyPairGenerator keyGen = KeyPairGenerator.getInstance("DSA", "SUN"); 044 045 SecureRandom random = SecureRandom.getInstance("SHA1PRNG", "SUN"); 046 keyGen.initialize(1024, random); 047 048 KeyPair pair = keyGen.generateKeyPair(); 049 PrivateKey priv = pair.getPrivate(); 050 PublicKey pub = pair.getPublic(); 051 052 // Save the public key in a file 053 byte[] key = pub.getEncoded(); 054 FileOutputStream keyfos = new FileOutputStream(new File(inOutputDir, "DSAKey.pub")); 055 keyfos.write(key); 056 keyfos.close(); 057 058 // Save the private key in a file 059 key = priv.getEncoded(); 060 keyfos = new FileOutputStream(new File(inOutputDir, "DSAKey.priv")); 061 keyfos.write(key); 062 keyfos.close(); 063 } 064 catch (Exception e) 065 { 066 throw new RuntimeException(e); 067 } 068 } 069 070 //-------------------------------------------------------------------------- 071 public static byte[] signData(PrivateKey inPrivateKey, byte[] inData) 072 { 073 return signData(inPrivateKey, new ByteArrayInputStream(inData)); 074 } 075 076 //-------------------------------------------------------------------------- 077 public static byte[] signData(PrivateKey inPrivateKey, InputStream inData) 078 { 079 byte[] sig; 080 try 081 { 082 try 083 { 084 Signature dsa = Signature.getInstance("SHA1withDSA", "SUN"); 085 dsa.initSign(inPrivateKey); 086 087 byte[] buffer = new byte[1024]; 088 int len; 089 while (inData.available() != 0) 090 { 091 len = inData.read(buffer); 092 dsa.update(buffer, 0, len); 093 } 094 095 sig = dsa.sign(); 096 } 097 finally 098 { 099 if (inData != null) inData.close(); 100 } 101 } 102 catch (Exception e) 103 { 104 throw new RuntimeException(e); 105 } 106 107 return sig; 108 } 109 110 111 //-------------------------------------------------------------------------- 112 public static boolean verifySignature(PublicKey inPublicKey, byte[] inData, byte[] inSignature) 113 { 114 return verifySignature(inPublicKey, new ByteArrayInputStream(inData), inSignature); 115 } 116 117 //-------------------------------------------------------------------------- 118 public static boolean verifySignature(PublicKey inPublicKey, InputStream inData, byte[] inSignature) 119 { 120 boolean result = false; 121 try 122 { 123 try 124 { 125 Signature sig = Signature.getInstance("SHA1withDSA", "SUN"); 126 sig.initVerify(inPublicKey); 127 128 byte[] buffer = new byte[1024]; 129 int len; 130 while (inData.available() != 0) 131 { 132 len = inData.read(buffer); 133 sig.update(buffer, 0, len); 134 } 135 136 result = sig.verify(inSignature); 137 } 138 finally 139 { 140 if (inData != null) inData.close(); 141 } 142 } 143 catch (Exception e) 144 { 145 throw new RuntimeException(e); 146 } 147 148 return result; 149 } 150 151 //-------------------------------------------------------------------------- 152 public static PublicKey readPublicKey(File inX509EncodedPublicKeyFile) 153 { 154 byte[] encKey; 155 156 try 157 { 158 FileInputStream keyfis = new FileInputStream(inX509EncodedPublicKeyFile); 159 encKey = new byte[keyfis.available()]; 160 keyfis.read(encKey); 161 keyfis.close(); 162 } 163 catch (Exception e) 164 { 165 throw new RuntimeException(e); 166 } 167 168 return readPublicKey(encKey); 169 } 170 171 //-------------------------------------------------------------------------- 172 public static PublicKey readPublicKey(InputStream inX509EncodedPublicKeyStream) 173 { 174 byte[] encKey; 175 176 try 177 { 178 try 179 { 180 ByteArrayOutputStream outStream = new ByteArrayOutputStream(); 181 byte[] buffer = new byte[1024]; 182 int len; 183 while ((len = inX509EncodedPublicKeyStream.read(buffer)) != -1) 184 { 185 outStream.write(buffer, 0, len); 186 } 187 188 outStream.close(); 189 encKey = outStream.toByteArray(); 190 } 191 finally 192 { 193 inX509EncodedPublicKeyStream.close(); 194 } 195 } 196 catch (Exception e) 197 { 198 throw new RuntimeException(e); 199 } 200 201 return readPublicKey(encKey); 202 } 203 204 //-------------------------------------------------------------------------- 205 public static PublicKey readPublicKey(byte[] inX509EncodedPublicKey) 206 { 207 PublicKey pubKey; 208 209 try 210 { 211 X509EncodedKeySpec pubKeySpec = new X509EncodedKeySpec(inX509EncodedPublicKey); 212 KeyFactory keyFactory = KeyFactory.getInstance("DSA", "SUN"); 213 pubKey = keyFactory.generatePublic(pubKeySpec); 214 } 215 catch (Exception e) 216 { 217 throw new RuntimeException(e); 218 } 219 220 return pubKey; 221 } 222 223 224 //-------------------------------------------------------------------------- 225 public static PrivateKey readPrivateKey(File inPKCS8EncodedPrivateKeyFile) 226 { 227 byte[] encKey; 228 229 try 230 { 231 FileInputStream keyfis = new FileInputStream(inPKCS8EncodedPrivateKeyFile); 232 encKey = new byte[keyfis.available()]; 233 keyfis.read(encKey); 234 keyfis.close(); 235 } 236 catch (Exception e) 237 { 238 throw new RuntimeException(e); 239 } 240 241 return readPrivateKey(encKey); 242 } 243 244 245 //-------------------------------------------------------------------------- 246 public static PrivateKey readPrivateKey(InputStream inPKCS8EncodedPrivateKeyStream) 247 { 248 byte[] encKey = null; 249 250 if (inPKCS8EncodedPrivateKeyStream != null) 251 { 252 try 253 { 254 try 255 { 256 ByteArrayOutputStream outStream = new ByteArrayOutputStream(); 257 byte[] buffer = new byte[1024]; 258 int len; 259 while ((len = inPKCS8EncodedPrivateKeyStream.read(buffer)) != -1) 260 { 261 outStream.write(buffer, 0, len); 262 } 263 264 outStream.close(); 265 encKey = outStream.toByteArray(); 266 } 267 finally 268 { 269 inPKCS8EncodedPrivateKeyStream.close(); 270 } 271 } 272 catch (Exception e) 273 { 274 throw new RuntimeException(e); 275 } 276 } 277 278 return readPrivateKey(encKey); 279 } 280 281 //-------------------------------------------------------------------------- 282 public static PrivateKey readPrivateKey(byte[] inPKCS8EncodedPrivateKey) 283 { 284 PrivateKey privKey = null; 285 286 if (inPKCS8EncodedPrivateKey != null) 287 { 288 try 289 { 290 PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(inPKCS8EncodedPrivateKey); 291 KeyFactory keyFactory = KeyFactory.getInstance("DSA", "SUN"); 292 privKey = keyFactory.generatePrivate(keySpec); 293 } 294 catch (Exception e) 295 { 296 throw new RuntimeException(e); 297 } 298 } 299 300 return privKey; 301 } 302}