any_rsa_pkcs1signature.java
来自「jpeg2000编解码」· Java 代码 · 共 494 行 · 第 1/2 页
JAVA
494 行
* been generated with. * @exception InvalidKeyException * If the key class does not implement java.security.interfaces.RSAPrivateKey * or * If the size of the minimal PKCS#1 frame generated by the * engineSign() method will be larger than the public key modulus. */ protected void engineInitVerify (PublicKey key) throws InvalidKeyException { if (!(key instanceof CryptixRSAPublicKey)) throw new InvalidKeyException(getAlgorithm() + ": Not an RSA public key"); CryptixRSAPublicKey rsa = (CryptixRSAPublicKey) key; n = rsa.getModulus(); exp = rsa.getExponent(); // It is unusual for an RSAPublicKey class to implement RSAFactors, // because knowing p and q implies knowing the private key. Still, // occasionally it is useful to verify a signature that you created, // and this can be used to make that more efficient. if (key instanceof RSAFactors) { RSAFactors factors = (RSAFactors) key; p = factors.getP(); q = factors.getQ(); u = factors.getInverseOfQModP(); } md.reset(); // result will have as many bytes as the public modulus n int mdl = md.digest().length; int length = (n.bitLength() + 7) / 8; int aidl = getAlgorithmEncoding().length; int padLen = length - 3 - aidl - mdl; if (padLen < 0) throw new InvalidKeyException("Signer's public key modulus too short."); } /** * Updates the data to be signed or verified, using one byte. * * @param b the byte to use for the update process. * @exception SignatureException if the engine is not initialised properly. */ protected void engineUpdate (byte b) throws SignatureException { if (state != VERIFY && state != SIGN) throw new SignatureException(getAlgorithm() + ": Not initialized"); md.update(b); } /** * Updates the data to be signed or verified, using the specified * sub-array of bytes, starting at the specified offset. * * @param in the array of bytes. * @param offset the offset to start from in <i>in</i>. * @param length the number of bytes to use, starting at <i>offset</i>. * @exception SignatureException if the engine is not initialised properly. */ protected void engineUpdate (byte[] in, int offset, int length) throws SignatureException { if (state != VERIFY && state != SIGN) throw new SignatureException(getAlgorithm() + ": Not initialized"); md.update(in, offset, length); } /** * Terminates the update process and returns the signature bytes of * all the data signed so far. * <p> * <b>NOTES:</b> Sun's documentation talks about the bytes returned * being X.509-encoded. For this RSA/PKCS#1 implementation, they * conform to PKCS#1 section 10. Practically, the return value will * be formed by concatenating a leading <i>NULL</i> byte, a block type * <i>BT</i>, a padding block <i>PS</i>, another <i>NULL</i>byte, and * finally a data block <i>D</i>; * ie: * <pre> * return = 0x00 || BT || PS || 0x00 || D. * </pre> * For signing, <i>PKCS#1 block type 01</i> encryption-block formatting * scheme is employed. The block type <i>BT</i> is a single byte valued * 0x01 and the padding block <i>PS</i> is enough 0xFF bytes to make the * length of the complete RSA Multi Precision Integer equal to the length * of the public modulus. The data block <i>D</i> consists of the MIC -- * Message Integrity Check, or message digest value-- and the MIC * algorithm ASN.1 encoded identifier. The formal syntax in ASN.1 * notation is: * <pre> * SEQUENCE { * digestAlgorithm AlgorithmIdentifier, * digest OCTET STRING * } * * AlgorithmIdentifier ::= SEQUENCE { * algorithm OBJECT IDENTIFIER, * parameters ANY DEFINED BY algorithm OPTIONAL * } * </pre> * * @return the signature bytes of the signing operation's result. * @exception SignatureException * if the engine is not initialised properly. */ protected byte[] engineSign() throws SignatureException { if (state != SIGN) throw new SignatureException( getAlgorithm() + ": Not initialized for signing"); long t = 0;if (DEBUG && debuglevel >= 7) t = System.currentTimeMillis(); BigInteger pkcs = makePKCS1(); BigInteger result = RSAAlgorithm.rsa(pkcs, n, exp, p, q, u);if (DEBUG && debuglevel >= 7) { t = System.currentTimeMillis() - t; debug(" ...engineSign() completed in "+t+" ms.");} return result.toByteArray(); } /** * Terminates the update process and verifies that the passed signature * equals that of a generated one based on the updated data so far. * <p> * <b>NOTES:</b> Sun's documentation talks about the bytes received * being X.509-encoded. For this RSA/PKCS#1 implementation, the bytes * received are assumed to conform to PKCS#1 section 10, or have * been generated by a previous invocation of the <code>engineSign</code> * method. * * @param signature the signature bytes to be verified. * @return true if the signature was verified successfully, false * otherwise. * @exception SignatureException if the engine is not initialised * properly, the received signature data is improperly * encoded or of the wrong type, etc. */ protected boolean engineVerify(byte[] signature) throws SignatureException { if (state != VERIFY) throw new SignatureException( getAlgorithm() + ": Not initialized for verification"); long t = 0;if (DEBUG && debuglevel >= 7) t = System.currentTimeMillis(); // if we generated it, it's a positive BI BigInteger M = new BigInteger(1,signature); BigInteger computed = RSAAlgorithm.rsa(M, n, exp, p, q, u); BigInteger actual = makePKCS1(); boolean ok = computed.equals(actual);if (DEBUG && debuglevel >= 7) { t = System.currentTimeMillis() - t; debug(" ...engineVerify() completed in "+t+" ms."); if (!ok) { debug(" Computed: " + Hex.dumpString(computed.toByteArray())); debug(" Actual: " + Hex.dumpString(actual.toByteArray())); }} return ok; } protected void engineSetParameter(String param, Object value) throws InvalidParameterException { throw new InvalidParameterException(getAlgorithm() + ": " + param); } protected Object engineGetParameter(String param) throws InvalidParameterException { throw new InvalidParameterException(getAlgorithm() + ": " + param); }// Own methods//........................................................................... /** * Returns a byte array consisting of a padded message digest value, * previously computed. This packet will be RSA-encrypted with the * private key of this object to act as an authentication for whatever * was digested. * <p> * As described in the <i>engineSign()</i> method above, the return * array will consist of: * <pre> * MSB LSB * 00 01 FF-1 ... FF-n 00 AID-1 ... AID-n 04 LL MD-1 ... MD-n * | BT |----- PS -----| |-- AlgorithmId --|------ digest ------| * </pre> * <p> * The <i>AID<i> bytes form the <i>AlgorithmIdentifier</i> token. * The OCTET STRING tag is <i>04</i> and <i>LL</i> is the length byte * (the number of bytes in the message digest proper, i.e. <i>n</i>). * <p> * Bytes <i>MD-1</i> to <i>MD-n</i> are the message digest value * of the material updated so far, thus completing the <i>digest</i> * token in the SEQUENCE described in <i>engineSign()</i> above. * * @return the result of the updating process framed in a PKCS#1 * type 01 block structure as a BigInteger. * @exception SignatureException If the length of the minimal PKCS#1 frame * generated by this method will be longer than the public key modulus. */ private BigInteger makePKCS1() throws SignatureException { byte[] theMD = md.digest(); // stop hashing int mdl = theMD.length; // result has as many bytes as the public modulus int length = (n.bitLength() + 7) / 8; byte[] r = new byte[length]; r[1] = 0x01; // PKCS#1 encryption block type byte[] aid = getAlgorithmEncoding(); // get the AID bytes int aidl = aid.length;// int padLen = length - 3 - aidl - mdl - 2; // put padding bytes int padLen = length - 3 - aidl - mdl; // put padding bytes if (padLen < 0) throw new SignatureException("Signer's public key modulus too short."); for (int i = 0; i < padLen;) r[2 + i++] = (byte) 0xFF; System.arraycopy(aid, 0, r, padLen + 3, aidl); // copy the AID bytes // the next 2 bytes are now part of the subclass// r[length - mdl - 2] = 0x04; // tag it as an OCTET STRING// r[length - mdl - 1] = (byte) mdl; // and say how long it is System.arraycopy(theMD, 0, r, length - mdl, mdl); // now the md per seif (DEBUG && debuglevel >= 4) debug("PKCS#1 frame = " + Hex.dumpString(r)); return new BigInteger(r); // always positive because r[0] is 0 } /** * Returns the ASN.1 bytes of the <i>AlgorithmIdentifier</i> token described * in <code>engineSign()</code> method above. * * @return the <i>AlgorithmIdentifier</i> bytes. */ protected abstract byte[] getAlgorithmEncoding();}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?