protected void initKey(byte[] salt) { key = SHA256.getHashWithSalt(key, salt); for (int i = 0; i < keyIterations; i++) { key = SHA256.getHash(key, true); } cipher.setKey(key); key = SHA256.getHash(key, true); cipherForInitVector.setKey(key); }
public static byte[] createUserPasswordHash(String userName, char[] passwordChars) { // 不能用用户名和密码组成hash,否则重命名用户后将不能通过原来的密码登录 // TODO 如果不用固定的名称是否还有更好办法? userName = Constants.PROJECT_NAME; if (userName.length() == 0 && passwordChars.length == 0) { return new byte[0]; } return SHA256.getKeyPasswordHash(userName, passwordChars); }
/** * Calculate the hash-based message authentication code. * * @param key the key * @param message the message * @return the hash */ public static byte[] getHMAC(byte[] key, byte[] message) { key = normalizeKeyForHMAC(key); int len = message.length; int byteLen = 64 + Math.max(32, len); int intLen = getIntCount(byteLen); byte[] byteBuff = new byte[intLen * 4]; int[] intBuff = new int[intLen]; SHA256 sha = new SHA256(); byte[] iKey = new byte[64 + len]; byte[] oKey = new byte[64 + 32]; sha.calculateHMAC(key, message, len, iKey, oKey, byteBuff, intBuff); return sha.result; }
private void calculateHMAC(byte[] key, byte[] message, int len, byte[] iKey, byte[] oKey, byte[] byteBuff, int[] intBuff) { Arrays.fill(iKey, 0, 64, (byte) 0x36); xor(iKey, key, 64); System.arraycopy(message, 0, iKey, 64, len); calculateHash(iKey, 64 + len, byteBuff, intBuff); Arrays.fill(oKey, 0, 64, (byte) 0x5c); xor(oKey, key, 64); System.arraycopy(result, 0, oKey, 64, 32); calculateHash(oKey, 64 + 32, byteBuff, intBuff); }
/** * Calculate the hash code for the given data. * * @param data the data to hash * @param nullData if the data should be filled with zeros after calculating * the hash code * @return the hash code */ public static byte[] getHash(byte[] data, boolean nullData) { int len = data.length; int intLen = getIntCount(len); byte[] byteBuff = new byte[intLen * 4]; int[] intBuff = new int[intLen]; SHA256 sha = new SHA256(); sha.calculateHash(data, len, byteBuff, intBuff); if (nullData) { sha.fillWithNull(); Arrays.fill(intBuff, 0); Arrays.fill(byteBuff, (byte) 0); Arrays.fill(data, (byte) 0); } return sha.result; }
/** * Check the password of this user. * * @param userPasswordHash the password data (the user password hash) * @return true if the user password hash is correct */ public boolean validateUserPasswordHash(byte[] userPasswordHash) { if (userPasswordHash.length == 0 && passwordHash.length == 0) { return true; } if (userPasswordHash.length == 0) { userPasswordHash = SHA256.getKeyPasswordHash(getName(), new char[0]); } byte[] hash = SHA256.getHashWithSalt(userPasswordHash, salt); return Utils.compareSecure(hash, passwordHash); }
int[] hh = this.hh; byte[] result = this.result; int intLen = getIntCount(len); System.arraycopy(data, 0, byteBuff, 0, len); byteBuff[len] = (byte) 0x80; Arrays.fill(byteBuff, len + 1, intLen * 4, (byte) 0); for (int i = 0, j = 0; j < intLen; i += 4, j++) { intBuff[j] = readInt(byteBuff, i); int theta1 = rot(x, 17) ^ rot(x, 19) ^ (x >>> 10); x = w[i - 15]; int theta0 = rot(x, 7) ^ rot(x, 18) ^ (x >>> 3); w[i] = theta1 + w[i - 7] + theta0 + w[i - 16]; int t1 = h + (rot(e, 6) ^ rot(e, 11) ^ rot(e, 25)) + ((e & f) ^ ((~e) & g)) + K[i] + w[i]; int t2 = (rot(a, 2) ^ rot(a, 13) ^ rot(a, 22)) + ((a & b) ^ (a & c) ^ (b & c)); h = g; g = f; writeInt(result, i * 4, hh[i]);
/** * Set the user name password hash. A random salt is generated as well. * The parameter is filled with zeros after use. * * @param userPasswordHash the user name password hash */ public void setUserPasswordHash(byte[] userPasswordHash) { if (userPasswordHash != null) { if (userPasswordHash.length == 0) { salt = passwordHash = userPasswordHash; } else { salt = new byte[Constants.SALT_LEN]; MathUtils.randomBytes(salt); passwordHash = SHA256.getHashWithSalt(userPasswordHash, salt); } } this.userPasswordHash = userPasswordHash; }
private static byte[] normalizeKeyForHMAC(byte[] key) { if (key.length > 64) { key = getHash(key, false); } if (key.length < 64) { key = Arrays.copyOf(key, 64); } return key; }
private void init() throws IOException { if (xts != null) { return; } this.size = base.size() - HEADER_LENGTH; boolean newFile = size < 0; byte[] salt; if (newFile) { byte[] header = Arrays.copyOf(HEADER, BLOCK_SIZE); salt = MathUtils.secureRandomBytes(SALT_LENGTH); System.arraycopy(salt, 0, header, SALT_POS, salt.length); DataUtils.writeFully(base, 0, ByteBuffer.wrap(header)); size = 0; } else { salt = new byte[SALT_LENGTH]; DataUtils.readFully(base, SALT_POS, ByteBuffer.wrap(salt)); if ((size & BLOCK_SIZE_MASK) != 0) { size -= BLOCK_SIZE; } } AES cipher = new AES(); cipher.setKey(SHA256.getPBKDF2(encryptionKey, salt, HASH_ITERATIONS, 16)); encryptionKey = null; xts = new XTS(cipher); }
private byte[] calculateLobMac(long lobId) { byte[] lobMacSalt = null; if (session != null) { lobMacSalt = session.getLobMacSalt(); } if (lobMacSalt == null) { lobMacSalt = MathUtils.secureRandomBytes(LOB_MAC_SALT_LENGTH); if (session != null) { session.setLobMacSalt(lobMacSalt); } } byte[] data = new byte[8]; Utils.writeLong(data, 0, lobId); byte[] hmacData = SHA256.getHashWithSalt(data, lobMacSalt); return hmacData; }
/** * Calculate the hash code by using the given salt. The salt is appended * after the data before the hash code is calculated. After generating the * hash code, the data and all internal buffers are filled with zeros to avoid * keeping insecure data in memory longer than required (and possibly * swapped to disk). * * @param data the data to hash * @param salt the salt to use * @return the hash code */ public static byte[] getHashWithSalt(byte[] data, byte[] salt) { byte[] buff = new byte[data.length + salt.length]; System.arraycopy(data, 0, buff, 0, data.length); System.arraycopy(salt, 0, buff, data.length, salt.length); return getHash(buff, true); }
byte[] key = normalizeKeyForHMAC(password); SHA256 sha = new SHA256(); int len = 64 + Math.max(32, salt.length + 4); byte[] message = new byte[len]; int intLen = getIntCount(len); byte[] byteBuff = new byte[intLen * 4]; int[] intBuff = new int[intLen]; if (i == 0) { System.arraycopy(salt, 0, message, 0, salt.length); writeInt(message, salt.length, k); len = salt.length + 4; } else { len = 32; sha.calculateHMAC(key, message, len, iKey, oKey, byteBuff, intBuff); for (int j = 0; j < 32 && j + offset < resultLen; j++) { result[j + offset] ^= sha.result[j];
private void initStore() { Database db = session.getDatabase(); byte[] key = null; if (cipher != null && password != null) { char[] pass = password.optimize(session).getValue(session).getString().toCharArray(); key = SHA256.getKeyPasswordHash("script", pass); } String file = getFileName(); fileStorage = FileStorage.open(db, file, "rw", cipher, key); fileStorage.setCheckedWriting(false); fileStorage.init(); }
private static byte[] getHash(String algorithm, byte[] bytes, int iterations) { if (!"SHA256".equalsIgnoreCase(algorithm)) { throw DbException.getInvalidValueException("algorithm", algorithm); } for (int i = 0; i < iterations; i++) { bytes = SHA256.getHash(bytes, false); } return bytes; }
/** * Calculate the hash of a password by prepending the user name and a '@' * character. Both the user name and the password are encoded to a byte * array using UTF-16. After generating the hash code, the password array * and all internal buffers are filled with zeros to avoid keeping the plain text * password in memory longer than required (and possibly swapped to disk). * * @param userName the user name * @param password the password * @return the hash code */ public static byte[] getKeyPasswordHash(String userName, char[] password) { String user = userName + "@"; byte[] buff = new byte[2 * (user.length() + password.length)]; int n = 0; for (int i = 0, length = user.length(); i < length; i++) { char c = user.charAt(i); buff[n++] = (byte) (c >> 8); buff[n++] = (byte) c; } for (char c : password) { buff[n++] = (byte) (c >> 8); buff[n++] = (byte) c; } Arrays.fill(password, (char) 0); return getHash(buff, true); }