📄 sha1.java
字号:
package net.propero.rdp.crypto;
/**
* This class implements the SHA-1 message digest algorithm.
* <p>
* <b>BUG</b>: The update method is missing.
* <p>
* <b>References:</b>
* <ol>
* <li> Bruce Schneier,
* "Section 18.7 Secure Hash Algorithm (SHA),"
* <cite>Applied Cryptography, 2nd edition</cite>,
* John Wiley & Sons, 1996
* <p>
* <li> NIST FIPS PUB 180-1,
* "Secure Hash Standard",
* U.S. Department of Commerce, May 1993.<br>
* <a href="http://www.itl.nist.gov/div897/pubs/fip180-1.htm">
* http://www.itl.nist.gov/div897/pubs/fip180-1.htm</a>
* </ol>
* <p>
* <b>Copyright</b> © 1995-1997
* <a href="http://www.systemics.com/">Systemics Ltd</a> on behalf of the
* <a href="http://www.systemics.com/docs/cryptix/">Cryptix Development Team</a>.
* <br>All rights reserved.
* <p>
* <b>$Revision: 1.6 $</b>
* @author Systemics Ltd
* @author David Hopwood
* @since Cryptix 2.2.2
*/
public final class SHA1
extends BlockMessageDigest
implements Cloneable
{
// SHA-1 constants and variables
//...........................................................................
/**
* Length of the final hash (in bytes).
*/
private static final int HASH_LENGTH = 20;
/**
* Length of a block (i.e. the number of bytes hashed in every transform).
*/
private static final int DATA_LENGTH = 64;
private int[] data;
private int[] digest;
private byte[] tmp;
private int[] w;
/**
* Returns the length of the hash (in bytes).
*/
protected int engineGetDigestLength() {
return HASH_LENGTH;
}
/**
* Returns the length of the data (in bytes) hashed in every transform.
*/
protected int engineGetDataLength()
{
return DATA_LENGTH;
}
/**
* Constructs a SHA-1 message digest.
*/
public SHA1()
{
super("SHA-1");
java_init();
engineReset();
}
private void java_init()
{
digest = new int[HASH_LENGTH/4];
data = new int[DATA_LENGTH/4];
tmp = new byte[DATA_LENGTH];
w = new int[80];
}
/**
* This constructor is here to implement cloneability of this class.
*/
private SHA1 (SHA1 md) {
this();
data = (int[])md.data.clone();
digest = (int[])md.digest.clone();
tmp = (byte[])md.tmp.clone();
w = (int[])md.w.clone();
}
/**
* Returns a copy of this MD object.
*/
public Object clone() { return new SHA1(this); }
/**
* Initializes (resets) the message digest.
*/
public void engineReset()
{
super.engineReset();
java_reset();
}
private void java_reset()
{
digest[0] = 0x67452301;
digest[1] = 0xefcdab89;
digest[2] = 0x98badcfe;
digest[3] = 0x10325476;
digest[4] = 0xc3d2e1f0;
}
/**
* Adds data to the message digest.
*
* @param data The data to be added.
* @param offset The start of the data in the array.
* @param length The amount of data to add.
*/
protected void engineTransform(byte[] in)
{
java_transform(in);
}
private void java_transform(byte[] in)
{
byte2int(in, 0, data, 0, DATA_LENGTH/4);
transform(data);
}
/**
* Returns the digest of the data added and resets the digest.
* @return the digest of all the data added to the message digest as a byte array.
*/
public byte[] engineDigest(byte[] in, int length)
{
byte b[] = java_digest(in, length);
engineReset();
return b;
}
private byte[] java_digest(byte[] in, int pos)
{
if (pos != 0) System.arraycopy(in, 0, tmp, 0, pos);
tmp[pos++] = (byte)0x80;
if (pos > DATA_LENGTH - 8)
{
while (pos < DATA_LENGTH)
tmp[pos++] = 0;
byte2int(tmp, 0, data, 0, DATA_LENGTH/4);
transform(data);
pos = 0;
}
while (pos < DATA_LENGTH - 8)
tmp[pos++] = 0;
byte2int(tmp, 0, data, 0, (DATA_LENGTH/4)-2);
// Big endian
// WARNING: int>>>32 != 0 !!!
// bitcount() used to return a long, now it's an int.
int bc = bitcount();
data[14] = 0;
data[15] = bc;
transform(data);
byte buf[] = new byte[HASH_LENGTH];
// Big endian
int off = 0;
for (int i = 0; i < HASH_LENGTH/4; ++i) {
int d = digest[i];
buf[off++] = (byte) (d>>>24);
buf[off++] = (byte) (d>>>16);
buf[off++] = (byte) (d>>>8);
buf[off++] = (byte) d;
}
return buf;
}
// SHA-1 transform routines
//...........................................................................
private static int f1(int a, int b, int c) { return (c^(a&(b^c))) + 0x5A827999; }
private static int f2(int a, int b, int c) { return (a^b^c) + 0x6ED9EBA1; }
private static int f3(int a, int b, int c) { return ((a&b)|(c&(a|b))) + 0x8F1BBCDC; }
private static int f4(int a, int b, int c) { return (a^b^c) + 0xCA62C1D6; }
private void transform (int[] X)
{
int A = digest[0];
int B = digest[1];
int C = digest[2];
int D = digest[3];
int E = digest[4];
int W[] = w;
for (int i=0; i<16; i++)
{
W[i] = X[i];
}
for (int i=16; i<80; i++)
{
int j = W[i-16] ^ W[i-14] ^ W[i-8] ^ W[i-3];
W[i] = j;
W[i] = (j << 1) | (j >>> -1);
}
E += ((A << 5)|(A >>> -5)) + f1(B, C, D) + W[0]; B =((B << 30)|(B >>> -30));
D += ((E << 5)|(E >>> -5)) + f1(A, B, C) + W[1]; A =((A << 30)|(A >>> -30));
C += ((D << 5)|(D >>> -5)) + f1(E, A, B) + W[2]; E =((E << 30)|(E >>> -30));
B += ((C << 5)|(C >>> -5)) + f1(D, E, A) + W[3]; D =((D << 30)|(D >>> -30));
A += ((B << 5)|(B >>> -5)) + f1(C, D, E) + W[4]; C =((C << 30)|(C >>> -30));
E += ((A << 5)|(A >>> -5)) + f1(B, C, D) + W[5]; B =((B << 30)|(B >>> -30));
D += ((E << 5)|(E >>> -5)) + f1(A, B, C) + W[6]; A =((A << 30)|(A >>> -30));
C += ((D << 5)|(D >>> -5)) + f1(E, A, B) + W[7]; E =((E << 30)|(E >>> -30));
B += ((C << 5)|(C >>> -5)) + f1(D, E, A) + W[8]; D =((D << 30)|(D >>> -30));
A += ((B << 5)|(B >>> -5)) + f1(C, D, E) + W[9]; C =((C << 30)|(C >>> -30));
E += ((A << 5)|(A >>> -5)) + f1(B, C, D) + W[10]; B =((B << 30)|(B >>> -30));
D += ((E << 5)|(E >>> -5)) + f1(A, B, C) + W[11]; A =((A << 30)|(A >>> -30));
C += ((D << 5)|(D >>> -5)) + f1(E, A, B) + W[12]; E =((E << 30)|(E >>> -30));
B += ((C << 5)|(C >>> -5)) + f1(D, E, A) + W[13]; D =((D << 30)|(D >>> -30));
A += ((B << 5)|(B >>> -5)) + f1(C, D, E) + W[14]; C =((C << 30)|(C >>> -30));
E += ((A << 5)|(A >>> -5)) + f1(B, C, D) + W[15]; B =((B << 30)|(B >>> -30));
D += ((E << 5)|(E >>> -5)) + f1(A, B, C) + W[16]; A =((A << 30)|(A >>> -30));
C += ((D << 5)|(D >>> -5)) + f1(E, A, B) + W[17]; E =((E << 30)|(E >>> -30));
B += ((C << 5)|(C >>> -5)) + f1(D, E, A) + W[18]; D =((D << 30)|(D >>> -30));
A += ((B << 5)|(B >>> -5)) + f1(C, D, E) + W[19]; C =((C << 30)|(C >>> -30));
E += ((A << 5)|(A >>> -5)) + f2(B, C, D) + W[20]; B =((B << 30)|(B >>> -30));
D += ((E << 5)|(E >>> -5)) + f2(A, B, C) + W[21]; A =((A << 30)|(A >>> -30));
C += ((D << 5)|(D >>> -5)) + f2(E, A, B) + W[22]; E =((E << 30)|(E >>> -30));
B += ((C << 5)|(C >>> -5)) + f2(D, E, A) + W[23]; D =((D << 30)|(D >>> -30));
A += ((B << 5)|(B >>> -5)) + f2(C, D, E) + W[24]; C =((C << 30)|(C >>> -30));
E += ((A << 5)|(A >>> -5)) + f2(B, C, D) + W[25]; B =((B << 30)|(B >>> -30));
D += ((E << 5)|(E >>> -5)) + f2(A, B, C) + W[26]; A =((A << 30)|(A >>> -30));
C += ((D << 5)|(D >>> -5)) + f2(E, A, B) + W[27]; E =((E << 30)|(E >>> -30));
B += ((C << 5)|(C >>> -5)) + f2(D, E, A) + W[28]; D =((D << 30)|(D >>> -30));
A += ((B << 5)|(B >>> -5)) + f2(C, D, E) + W[29]; C =((C << 30)|(C >>> -30));
E += ((A << 5)|(A >>> -5)) + f2(B, C, D) + W[30]; B =((B << 30)|(B >>> -30));
D += ((E << 5)|(E >>> -5)) + f2(A, B, C) + W[31]; A =((A << 30)|(A >>> -30));
C += ((D << 5)|(D >>> -5)) + f2(E, A, B) + W[32]; E =((E << 30)|(E >>> -30));
B += ((C << 5)|(C >>> -5)) + f2(D, E, A) + W[33]; D =((D << 30)|(D >>> -30));
A += ((B << 5)|(B >>> -5)) + f2(C, D, E) + W[34]; C =((C << 30)|(C >>> -30));
E += ((A << 5)|(A >>> -5)) + f2(B, C, D) + W[35]; B =((B << 30)|(B >>> -30));
D += ((E << 5)|(E >>> -5)) + f2(A, B, C) + W[36]; A =((A << 30)|(A >>> -30));
C += ((D << 5)|(D >>> -5)) + f2(E, A, B) + W[37]; E =((E << 30)|(E >>> -30));
B += ((C << 5)|(C >>> -5)) + f2(D, E, A) + W[38]; D =((D << 30)|(D >>> -30));
A += ((B << 5)|(B >>> -5)) + f2(C, D, E) + W[39]; C =((C << 30)|(C >>> -30));
E += ((A << 5)|(A >>> -5)) + f3(B, C, D) + W[40]; B =((B << 30)|(B >>> -30));
D += ((E << 5)|(E >>> -5)) + f3(A, B, C) + W[41]; A =((A << 30)|(A >>> -30));
C += ((D << 5)|(D >>> -5)) + f3(E, A, B) + W[42]; E =((E << 30)|(E >>> -30));
B += ((C << 5)|(C >>> -5)) + f3(D, E, A) + W[43]; D =((D << 30)|(D >>> -30));
A += ((B << 5)|(B >>> -5)) + f3(C, D, E) + W[44]; C =((C << 30)|(C >>> -30));
E += ((A << 5)|(A >>> -5)) + f3(B, C, D) + W[45]; B =((B << 30)|(B >>> -30));
D += ((E << 5)|(E >>> -5)) + f3(A, B, C) + W[46]; A =((A << 30)|(A >>> -30));
C += ((D << 5)|(D >>> -5)) + f3(E, A, B) + W[47]; E =((E << 30)|(E >>> -30));
B += ((C << 5)|(C >>> -5)) + f3(D, E, A) + W[48]; D =((D << 30)|(D >>> -30));
A += ((B << 5)|(B >>> -5)) + f3(C, D, E) + W[49]; C =((C << 30)|(C >>> -30));
E += ((A << 5)|(A >>> -5)) + f3(B, C, D) + W[50]; B =((B << 30)|(B >>> -30));
D += ((E << 5)|(E >>> -5)) + f3(A, B, C) + W[51]; A =((A << 30)|(A >>> -30));
C += ((D << 5)|(D >>> -5)) + f3(E, A, B) + W[52]; E =((E << 30)|(E >>> -30));
B += ((C << 5)|(C >>> -5)) + f3(D, E, A) + W[53]; D =((D << 30)|(D >>> -30));
A += ((B << 5)|(B >>> -5)) + f3(C, D, E) + W[54]; C =((C << 30)|(C >>> -30));
E += ((A << 5)|(A >>> -5)) + f3(B, C, D) + W[55]; B =((B << 30)|(B >>> -30));
D += ((E << 5)|(E >>> -5)) + f3(A, B, C) + W[56]; A =((A << 30)|(A >>> -30));
C += ((D << 5)|(D >>> -5)) + f3(E, A, B) + W[57]; E =((E << 30)|(E >>> -30));
B += ((C << 5)|(C >>> -5)) + f3(D, E, A) + W[58]; D =((D << 30)|(D >>> -30));
A += ((B << 5)|(B >>> -5)) + f3(C, D, E) + W[59]; C =((C << 30)|(C >>> -30));
E += ((A << 5)|(A >>> -5)) + f4(B, C, D) + W[60]; B =((B << 30)|(B >>> -30));
D += ((E << 5)|(E >>> -5)) + f4(A, B, C) + W[61]; A =((A << 30)|(A >>> -30));
C += ((D << 5)|(D >>> -5)) + f4(E, A, B) + W[62]; E =((E << 30)|(E >>> -30));
B += ((C << 5)|(C >>> -5)) + f4(D, E, A) + W[63]; D =((D << 30)|(D >>> -30));
A += ((B << 5)|(B >>> -5)) + f4(C, D, E) + W[64]; C =((C << 30)|(C >>> -30));
E += ((A << 5)|(A >>> -5)) + f4(B, C, D) + W[65]; B =((B << 30)|(B >>> -30));
D += ((E << 5)|(E >>> -5)) + f4(A, B, C) + W[66]; A =((A << 30)|(A >>> -30));
C += ((D << 5)|(D >>> -5)) + f4(E, A, B) + W[67]; E =((E << 30)|(E >>> -30));
B += ((C << 5)|(C >>> -5)) + f4(D, E, A) + W[68]; D =((D << 30)|(D >>> -30));
A += ((B << 5)|(B >>> -5)) + f4(C, D, E) + W[69]; C =((C << 30)|(C >>> -30));
E += ((A << 5)|(A >>> -5)) + f4(B, C, D) + W[70]; B =((B << 30)|(B >>> -30));
D += ((E << 5)|(E >>> -5)) + f4(A, B, C) + W[71]; A =((A << 30)|(A >>> -30));
C += ((D << 5)|(D >>> -5)) + f4(E, A, B) + W[72]; E =((E << 30)|(E >>> -30));
B += ((C << 5)|(C >>> -5)) + f4(D, E, A) + W[73]; D =((D << 30)|(D >>> -30));
A += ((B << 5)|(B >>> -5)) + f4(C, D, E) + W[74]; C =((C << 30)|(C >>> -30));
E += ((A << 5)|(A >>> -5)) + f4(B, C, D) + W[75]; B =((B << 30)|(B >>> -30));
D += ((E << 5)|(E >>> -5)) + f4(A, B, C) + W[76]; A =((A << 30)|(A >>> -30));
C += ((D << 5)|(D >>> -5)) + f4(E, A, B) + W[77]; E =((E << 30)|(E >>> -30));
B += ((C << 5)|(C >>> -5)) + f4(D, E, A) + W[78]; D =((D << 30)|(D >>> -30));
A += ((B << 5)|(B >>> -5)) + f4(C, D, E) + W[79]; C =((C << 30)|(C >>> -30));
digest[0] += A;
digest[1] += B;
digest[2] += C;
digest[3] += D;
digest[4] += E;
}
// why was this public?
// Note: parameter order changed to be consistent with System.arraycopy.
private static void byte2int(byte[] src, int srcOffset,
int[] dst, int dstOffset, int length)
{
while (length-- > 0)
{
// Big endian
dst[dstOffset++] = (src[srcOffset++] << 24) |
((src[srcOffset++] & 0xFF) << 16) |
((src[srcOffset++] & 0xFF) << 8) |
(src[srcOffset++] & 0xFF);
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -