?? iso9796d2psssigner.java
字號:
block[off] = 0x01; System.arraycopy(mBuf, 0, block, off + 1, messageLength); System.arraycopy(salt, 0, block, off + 1 + messageLength, salt.length); byte[] dbMask = maskGeneratorFunction1(hash, 0, hash.length, block.length - hLen - tLength); for (int i = 0; i != dbMask.length; i++) { block[i] ^= dbMask[i]; } System.arraycopy(hash, 0, block, block.length - hLen - tLength, hLen); if (trailer == TRAILER_IMPLICIT) { block[block.length - 1] = (byte)TRAILER_IMPLICIT; } else { block[block.length - 2] = (byte)(trailer >>> 8); block[block.length - 1] = (byte)trailer; } block[0] &= 0x7f; byte[] b = cipher.processBlock(block, 0, block.length); clearBlock(mBuf); clearBlock(block); messageLength = 0; return b; } /** * return true if the signature represents a ISO9796-2 signature * for the passed in message. */ public boolean verifySignature( byte[] signature) { byte[] block = null; try { block = cipher.processBlock(signature, 0, signature.length); } catch (Exception e) { return false; } // // adjust block size for leading zeroes if necessary // if (block.length < (keyBits + 7) / 8) { byte[] tmp = new byte[(keyBits + 7) / 8]; System.arraycopy(block, 0, tmp, tmp.length - block.length, block.length); block = tmp; } int tLength = 0; if (((block[block.length - 1] & 0xFF) ^ 0xBC) == 0) { tLength = 1; } else { int sigTrail = ((block[block.length - 2] & 0xFF) << 8) | (block[block.length - 1] & 0xFF); switch (sigTrail) { case TRAILER_RIPEMD160: if (!(digest instanceof RIPEMD160Digest)) { throw new IllegalStateException("signer should be initialised with RIPEMD160"); } break; case TRAILER_SHA1: if (!(digest instanceof SHA1Digest)) { throw new IllegalStateException("signer should be initialised with SHA1"); } break; case TRAILER_RIPEMD128: if (!(digest instanceof RIPEMD128Digest)) { throw new IllegalStateException("signer should be initialised with RIPEMD128"); } break; default: throw new IllegalArgumentException("unrecognised hash in signature"); } tLength = 2; } // // calculate H(m2) // byte[] m2Hash = new byte[hLen]; digest.doFinal(m2Hash, 0); // // remove the mask // byte[] dbMask = maskGeneratorFunction1(block, block.length - hLen - tLength, hLen, block.length - hLen - tLength); for (int i = 0; i != dbMask.length; i++) { block[i] ^= dbMask[i]; } block[0] &= 0x7f; // // find out how much padding we've got // int mStart = 0; for (mStart = 0; mStart != block.length; mStart++) { if (block[mStart] == 0x01) { break; } } mStart++; if (mStart >= block.length) { clearBlock(block); return false; } if (mStart > 1) { fullMessage = true; } else { fullMessage = false; } recoveredMessage = new byte[dbMask.length - mStart - saltLength]; System.arraycopy(block, mStart, recoveredMessage, 0, recoveredMessage.length); // // check the hashes // byte[] C = new byte[8]; LtoOSP(recoveredMessage.length * 8, C); digest.update(C, 0, C.length); if (recoveredMessage.length != 0) { digest.update(recoveredMessage, 0, recoveredMessage.length); } digest.update(m2Hash, 0, m2Hash.length); byte[] hash = new byte[digest.getDigestSize()]; digest.update(block, mStart + recoveredMessage.length, dbMask.length - mStart - recoveredMessage.length); digest.doFinal(hash, 0); int off = block.length - tLength - hash.length; for (int i = 0; i != hash.length; i++) { if (hash[i] != block[off + i]) { clearBlock(block); clearBlock(hash); clearBlock(recoveredMessage); fullMessage = false; return false; } } // // if they've input a message check what we've recovered against // what was input. // if (messageLength != 0) { if (!isSameAs(mBuf, recoveredMessage)) { clearBlock(mBuf); clearBlock(block); return false; } } clearBlock(mBuf); clearBlock(block); messageLength = 0; return true; } /** * Return true if the full message was recoveredMessage. * * @return true on full message recovery, false otherwise, or if not sure. * @see org.bouncycastle.crypto.SignerWithRecovery#hasFullMessage() */ public boolean hasFullMessage() { return fullMessage; } /** * Return a reference to the recoveredMessage message. * * @return the full/partial recoveredMessage message. * @see org.bouncycastle.crypto.SignerWithRecovery#getRecoveredMessage() */ public byte[] getRecoveredMessage() { return recoveredMessage; } /** * int to octet string. */ private void ItoOSP( int i, byte[] sp) { sp[0] = (byte)(i >>> 24); sp[1] = (byte)(i >>> 16); sp[2] = (byte)(i >>> 8); sp[3] = (byte)(i >>> 0); } /** * long to octet string. */ private void LtoOSP( long l, byte[] sp) { sp[0] = (byte)(l >>> 56); sp[1] = (byte)(l >>> 48); sp[2] = (byte)(l >>> 40); sp[3] = (byte)(l >>> 32); sp[4] = (byte)(l >>> 24); sp[5] = (byte)(l >>> 16); sp[6] = (byte)(l >>> 8); sp[7] = (byte)(l >>> 0); } /** * mask generator function, as described in PKCS1v2. */ private byte[] maskGeneratorFunction1( byte[] Z, int zOff, int zLen, int length) { byte[] mask = new byte[length]; byte[] hashBuf = new byte[hLen]; byte[] C = new byte[4]; int counter = 0; digest.reset(); while (counter < (length / hLen)) { ItoOSP(counter, C); digest.update(Z, zOff, zLen); digest.update(C, 0, C.length); digest.doFinal(hashBuf, 0); System.arraycopy(hashBuf, 0, mask, counter * hLen, hLen); counter++; } if ((counter * hLen) < length) { ItoOSP(counter, C); digest.update(Z, zOff, zLen); digest.update(C, 0, C.length); digest.doFinal(hashBuf, 0); System.arraycopy(hashBuf, 0, mask, counter * hLen, mask.length - (counter * hLen)); } return mask; }}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -