x509signature.java

来自「RESIN 3.2 最新源码」· Java 代码 · 共 398 行

JAVA
398
字号
/* * Copyright (c) 2001-2004 Caucho Technology, Inc.  All rights reserved. * * The Apache Software License, Version 1.1 * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright *    notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright *    notice, this list of conditions and the following disclaimer in *    the documentation and/or other materials provided with the *    distribution. * * 3. The end-user documentation included with the redistribution, if *    any, must include the following acknowlegement: *       "This product includes software developed by the *        Caucho Technology (http://www.caucho.com/)." *    Alternately, this acknowlegement may appear in the software itself, *    if and wherever such third-party acknowlegements normally appear. * * 4. The names "Hessian", "Resin", and "Caucho" must not be used to *    endorse or promote products derived from this software without prior *    written permission. For written permission, please contact *    info@caucho.com. * * 5. Products derived from this software may not be called "Resin" *    nor may "Resin" appear in their names without prior written *    permission of Caucho Technology. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED.  IN NO EVENT SHALL CAUCHO TECHNOLOGY OR ITS CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * @author Scott Ferguson */package com.caucho.hessian.security;import java.security.*;import java.security.cert.*;import java.util.*;import javax.crypto.*;import java.io.*;import com.caucho.hessian.io.*;public class X509Signature extends HessianEnvelope {  private String _algorithm = "HmacSHA256";  private X509Certificate _cert;  private PrivateKey _privateKey;  private SecureRandom _secureRandom;    public X509Signature()  {  }  /**   * Sets the encryption algorithm for the content.   */  public void setAlgorithm(String algorithm)  {    if (algorithm == null)      throw new NullPointerException();        _algorithm = algorithm;  }  /**   * Gets the encryption algorithm for the content.   */  public String getAlgorithm()  {    return _algorithm;  }  /**   * The X509 certificate to obtain the public key of the recipient.   */  public X509Certificate getCertificate()  {    return _cert;  }  /**   * The X509 certificate to obtain the public key of the recipient.   */  public void setCertificate(X509Certificate cert)  {    _cert = cert;  }  /**   * The key to obtain the private key of the recipient.   */  public PrivateKey getPrivateKey()  {    return _privateKey;  }  /**   * The private key.   */  public void setPrivateKey(PrivateKey key)  {    _privateKey = key;  }  /**   * The random number generator for the shared secrets.   */  public SecureRandom getSecureRandom()  {    return _secureRandom;  }  /**   * The random number generator for the shared secrets.   */  public void setSecureRandom(SecureRandom random)  {    _secureRandom = random;  }  public Hessian2Output wrap(Hessian2Output out)    throws IOException  {    if (_privateKey == null)      throw new IOException("X509Signature.wrap requires a private key");        if (_cert == null)      throw new IOException("X509Signature.wrap requires a certificate");        OutputStream os = new SignatureOutputStream(out);        Hessian2Output filterOut = new Hessian2Output(os);    filterOut.setCloseStreamOnClose(true);        return filterOut;  }  public Hessian2Input unwrap(Hessian2Input in)    throws IOException  {    if (_cert == null)      throw new IOException("X509Signature.unwrap requires a certificate");        int version = in.readEnvelope();    String method = in.readMethod();    if (! method.equals(getClass().getName()))      throw new IOException("expected hessian Envelope method '" +			    getClass().getName() + "' at '" + method + "'");    return unwrapHeaders(in);  }  public Hessian2Input unwrapHeaders(Hessian2Input in)    throws IOException  {    if (_cert == null)      throw new IOException("X509Signature.unwrap requires a certificate");        InputStream is = new SignatureInputStream(in);    Hessian2Input filter = new Hessian2Input(is);    filter.setCloseStreamOnClose(true);        return filter;  }  class SignatureOutputStream extends OutputStream {    private Hessian2Output _out;    private OutputStream _bodyOut;    private Mac _mac;        SignatureOutputStream(Hessian2Output out)      throws IOException    {      try {        KeyGenerator keyGen = KeyGenerator.getInstance(_algorithm);        if (_secureRandom != null)          keyGen.init(_secureRandom);        SecretKey sharedKey = keyGen.generateKey();            _out = out;        _out.startEnvelope(X509Signature.class.getName());              PublicKey publicKey = _cert.getPublicKey();        byte []encoded = publicKey.getEncoded();        MessageDigest md = MessageDigest.getInstance("SHA1");        md.update(encoded);        byte []fingerprint = md.digest();        String keyAlgorithm = _privateKey.getAlgorithm();        Cipher keyCipher = Cipher.getInstance(keyAlgorithm);        keyCipher.init(Cipher.WRAP_MODE, _privateKey);        byte []encKey = keyCipher.wrap(sharedKey);            _out.writeInt(4);        _out.writeString("algorithm");        _out.writeString(_algorithm);        _out.writeString("fingerprint");        _out.writeBytes(fingerprint);        _out.writeString("key-algorithm");        _out.writeString(keyAlgorithm);        _out.writeString("key");        _out.writeBytes(encKey);        _mac = Mac.getInstance(_algorithm);        _mac.init(sharedKey);        _bodyOut = _out.getBytesOutputStream();      } catch (RuntimeException e) {        throw e;      } catch (IOException e) {        throw e;      } catch (Exception e) {        throw new RuntimeException(e);      }    }    public void write(int ch)      throws IOException    {      _bodyOut.write(ch);      _mac.update((byte) ch);    }    public void write(byte []buffer, int offset, int length)      throws IOException    {      _bodyOut.write(buffer, offset, length);      _mac.update(buffer, offset, length);    }    public void close()      throws IOException    {      Hessian2Output out = _out;      _out = null;      if (out == null)	return;            _bodyOut.close();      byte []sig = _mac.doFinal();      out.writeInt(1);      out.writeString("signature");      out.writeBytes(sig);      out.completeEnvelope();      out.close();    }  }    class SignatureInputStream extends InputStream {    private Hessian2Input _in;        private Mac _mac;    private InputStream _bodyIn;    private CipherInputStream _cipherIn;        SignatureInputStream(Hessian2Input in)      throws IOException    {      try {        _in = in;        byte []fingerprint = null;        String keyAlgorithm = null;        String algorithm = null;        byte []encKey = null;        int len = in.readInt();        for (int i = 0; i < len; i++) {          String header = in.readString();          if ("fingerprint".equals(header))            fingerprint = in.readBytes();          else if ("key-algorithm".equals(header))            keyAlgorithm = in.readString();          else if ("algorithm".equals(header))            algorithm = in.readString();          else if ("key".equals(header))            encKey = in.readBytes();          else            throw new IOException("'" + header + "' is an unexpected header");        }        Cipher keyCipher = Cipher.getInstance(keyAlgorithm);        keyCipher.init(Cipher.UNWRAP_MODE, _cert);        Key key = keyCipher.unwrap(encKey, algorithm, Cipher.SECRET_KEY);        _bodyIn = _in.readInputStream();        _mac = Mac.getInstance(algorithm);        _mac.init(key);      } catch (RuntimeException e) {        throw e;      } catch (IOException e) {        throw e;      } catch (Exception e) {        throw new RuntimeException(e);      }    }        public int read()      throws IOException    {      int ch = _bodyIn.read();      if (ch < 0)	return ch;      _mac.update((byte) ch);      return ch;    }        public int read(byte []buffer, int offset, int length)      throws IOException    {      int len = _bodyIn.read(buffer, offset, length);      if (len < 0)	return len;      _mac.update(buffer, offset, len);      return len;    }    public void close()      throws IOException    {      Hessian2Input in = _in;      _in = null;      if (in != null) {	_bodyIn.close();	int len = in.readInt();	byte []signature = null;	for (int i = 0; i < len; i++) {	  String header = in.readString();	  if ("signature".equals(header))	    signature = in.readBytes();	}        in.completeEnvelope();        in.close();          	if (signature == null)	  throw new IOException("Expected signature");	byte []sig = _mac.doFinal();	if (sig.length != signature.length)	  throw new IOException("mismatched signature");	for (int i = 0; i < sig.length; i++) {	  if (signature[i] != sig[i])	    throw new IOException("mismatched signature");	}	// XXX: save principal      }    }  }}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?