dsa.java

来自「This is a resource based on j2me embedde」· Java 代码 · 共 600 行 · 第 1/2 页

JAVA
600
字号
/* * @(#)DSA.java	1.94 06/10/10 * * Copyright  1990-2008 Sun Microsystems, Inc. All Rights Reserved.   * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER   *    * This program is free software; you can redistribute it and/or   * modify it under the terms of the GNU General Public License version   * 2 only, as published by the Free Software Foundation.    *    * This program is distributed in the hope that it will be useful, but   * WITHOUT ANY WARRANTY; without even the implied warranty of   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU   * General Public License version 2 for more details (a copy is   * included at /legal/license.txt).    *    * You should have received a copy of the GNU General Public License   * version 2 along with this work; if not, write to the Free Software   * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA   * 02110-1301 USA    *    * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa   * Clara, CA 95054 or visit www.sun.com if you need additional   * information or have any questions.  * */package sun.security.provider;import java.io.*;import java.util.*;import java.math.BigInteger;import java.security.AlgorithmParameters;import java.security.InvalidAlgorithmParameterException;import java.security.InvalidKeyException;import java.security.InvalidParameterException;import java.security.MessageDigest;import java.security.NoSuchAlgorithmException;import java.security.PublicKey;import java.security.PrivateKey;import java.security.SecureRandom;import java.security.Signature;import java.security.SignatureException;import java.security.interfaces.*;import java.security.spec.DSAParameterSpec;import java.security.spec.InvalidParameterSpecException;import sun.security.util.Debug;import sun.security.util.DerValue;import sun.security.util.DerInputStream;import sun.security.util.DerOutputStream;import sun.security.x509.AlgIdDSA;/** * The Digital Signature Standard (using the Digital Signature * Algorithm), as described in fips186 of the National Instute of * Standards and Technology (NIST), using fips180-1 (SHA-1). * * @author Benjamin Renaud * * @version 1.88, 02/02/00 * * @see DSAPublicKey * @see DSAPrivateKey */public final class DSA extends Signature {    /* Are we debugging? */    private static final boolean debug = false;    /* The parameter object */    private DSAParams params;    /* algorithm parameters */    private BigInteger presetP, presetQ, presetG;    /* The public key, if any */    private BigInteger presetY;    /* The private key, if any */    private BigInteger presetX;        /* The SHA hash for the data */    private MessageDigest dataSHA;    /* The random seed used to generate k */    private int[] Kseed;    /* The random seed used to generate k (specified by application) */    private byte[] KseedAsByteArray;    /*     * The random seed used to generate k     * (prevent the same Kseed from being used twice in a row     */    private int[] previousKseed;    /* The RNG used to output a seed for generating k */    private SecureRandom signingRandom;    /**     * Construct a blank DSA object. It can generate keys, but must be     * initialized before being usable for signing or verifying.     */    public DSA() throws NoSuchAlgorithmException {	super("SHA1withDSA");	dataSHA = MessageDigest.getInstance("SHA");    }    /**     * Initialize the DSA object with a DSA private key.     *      * @param privateKey the DSA private key     *      * @exception InvalidKeyException if the key is not a valid DSA private     * key.     */    protected void engineInitSign(PrivateKey privateKey)    throws InvalidKeyException {	if (!(privateKey instanceof java.security.interfaces.DSAPrivateKey)) {	    throw new InvalidKeyException("not a DSA private key: " +					  privateKey);	}        java.security.interfaces.DSAPrivateKey priv = 	    (java.security.interfaces.DSAPrivateKey)privateKey;	this.presetX = priv.getX();	initialize(priv.getParams());    }    /**     * Initialize the DSA object with a DSA public key.     *      * @param publicKey the DSA public key.     *      * @exception InvalidKeyException if the key is not a valid DSA public     * key.     */    protected void engineInitVerify(PublicKey publicKey)    throws InvalidKeyException {	if (!(publicKey instanceof java.security.interfaces.DSAPublicKey)) {	    throw new InvalidKeyException("not a DSA public key: " +					  publicKey);	}	java.security.interfaces.DSAPublicKey pub = 	    (java.security.interfaces.DSAPublicKey)publicKey;	this.presetY = pub.getY();	initialize(pub.getParams());    }    private void initialize(DSAParams params) throws InvalidKeyException {	dataSHA.reset();	setParams(params);    }    /**     * Sign all the data thus far updated. The signature is formatted     * according to the Canonical Encoding Rules, returned as a DER     * sequence of Integer, r and s.     *     * @return a signature block formatted according to the Canonical     * Encoding Rules.     *     * @exception SignatureException if the signature object was not     * properly initialized, or if another exception occurs.     *      * @see sun.security.DSA#engineUpdate     * @see sun.security.DSA#engineVerify     */    protected byte[] engineSign() throws SignatureException {		BigInteger k = generateK(presetQ);	BigInteger r = generateR(presetP, presetQ, presetG, k);	BigInteger s = generateS(presetX, presetQ, r, k);	try {	    DerOutputStream outseq = new DerOutputStream(100);	    outseq.putInteger(r);	    outseq.putInteger(s);	    DerValue result = new DerValue(DerValue.tag_Sequence,					   outseq.toByteArray());	    return result.toByteArray();	} catch (IOException e) {	    throw new SignatureException("error encoding signature");	}    }    /**     * Verify all the data thus far updated.      *     * @param signature the alledged signature, encoded using the     * Canonical Encoding Rules, as a sequence of integers, r and s.     *     * @exception SignatureException if the signature object was not     * properly initialized, or if another exception occurs.     *     * @see sun.security.DSA#engineUpdate     * @see sun.security.DSA#engineSign      */    protected boolean engineVerify(byte[] signature)     throws SignatureException {	return engineVerify(signature, 0, signature.length);    }    /**     * Verify all the data thus far updated.      *     * @param signature the alledged signature, encoded using the     * Canonical Encoding Rules, as a sequence of integers, r and s.     *     * @param offset the offset to start from in the array of bytes.     *     * @param length the number of bytes to use, starting at offset.     *     * @exception SignatureException if the signature object was not     * properly initialized, or if another exception occurs.     *     * @see sun.security.DSA#engineUpdate     * @see sun.security.DSA#engineSign      */    protected boolean engineVerify(byte[] signature, int offset, int length)     throws SignatureException {	BigInteger r = null;	BigInteger s = null;	// first decode the signature.	try {	    DerInputStream in = new DerInputStream(signature, offset, length);	    DerValue[] values = in.getSequence(2);	    r = values[0].getBigInteger();	    s = values[1].getBigInteger();	} catch (IOException e) {	    throw new SignatureException("invalid encoding for signature");	}	if ((r.compareTo(BigInteger.ZERO) == 1) &&	    (r.compareTo(presetQ) == -1) &&	    (s.compareTo(BigInteger.ZERO) == 1) &&	    (s.compareTo(presetQ) == -1)) {	    BigInteger w = generateW(presetP, presetQ, presetG, s);	    BigInteger v = generateV(presetY, presetP, presetQ, presetG, w, r);	    return v.equals(r);	} else {	    throw new SignatureException("invalid signature: out of range values");		}    }    private void reset() {	dataSHA.reset();    }    BigInteger generateR(BigInteger p, BigInteger q, BigInteger g,			 BigInteger k) {	BigInteger temp = g.modPow(k, p);	return temp.remainder(q);   }    BigInteger generateS(BigInteger x, BigInteger q, 				 BigInteger r, BigInteger k) {	byte[] s2 = dataSHA.digest();	BigInteger temp = new BigInteger(1, s2);	BigInteger k1 = k.modInverse(q);		BigInteger s = x.multiply(r);	s = temp.add(s);	s = k1.multiply(s);	return s.remainder(q);    }    BigInteger generateW(BigInteger p, BigInteger q,			 BigInteger g, BigInteger s) {	return s.modInverse(q);    }    BigInteger generateV(BigInteger y, BigInteger p,			 BigInteger q, BigInteger g,			 BigInteger w, BigInteger r) {	byte[] s2 = dataSHA.digest();	BigInteger temp = new BigInteger(1, s2);		temp = temp.multiply(w);	BigInteger u1 = temp.remainder(q);	BigInteger u2 = (r.multiply(w)).remainder(q);		BigInteger t1 = g.modPow(u1,p);	BigInteger t2 = y.modPow(u2,p);	BigInteger t3 = t1.multiply(t2);	BigInteger t5 = t3.remainder(p);	return t5.remainder(q);    }    /*

⌨️ 快捷键说明

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