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 + -
显示快捷键?