X-Git-Url: https://git.argeo.org/?a=blobdiff_plain;f=org.argeo.enterprise%2Fsrc%2Forg%2Fargeo%2Fosgi%2Fuseradmin%2FDigestUtils.java;h=511c2fede5e747e8e7e3adef942a09063793c579;hb=f9efbe5228615951dd8482a4582aa24e00c10ce5;hp=51d18349b2a662a762871e9464c5e24370a01c77;hpb=088c1b517a543e935d8ab65c3b2fd2d0269b551d;p=lgpl%2Fargeo-commons.git diff --git a/org.argeo.enterprise/src/org/argeo/osgi/useradmin/DigestUtils.java b/org.argeo.enterprise/src/org/argeo/osgi/useradmin/DigestUtils.java index 51d18349b..511c2fede 100644 --- a/org.argeo.enterprise/src/org/argeo/osgi/useradmin/DigestUtils.java +++ b/org.argeo.enterprise/src/org/argeo/osgi/useradmin/DigestUtils.java @@ -1,13 +1,21 @@ package org.argeo.osgi.useradmin; +import java.math.BigInteger; import java.nio.ByteBuffer; import java.nio.CharBuffer; import java.nio.charset.StandardCharsets; import java.security.MessageDigest; +import java.security.spec.KeySpec; import java.util.Arrays; +import javax.crypto.SecretKeyFactory; +import javax.crypto.spec.PBEKeySpec; + /** Utilities around digests, mostly those related to passwords. */ class DigestUtils { + final static String PASSWORD_SCHEME_SHA = "SHA"; + final static String PASSWORD_SCHEME_PBKDF2_SHA256 = "PBKDF2_SHA256"; + static byte[] sha1(byte[] bytes) { try { MessageDigest digest = MessageDigest.getInstance("SHA1"); @@ -19,6 +27,40 @@ class DigestUtils { } } + static byte[] toPasswordScheme(String passwordScheme, char[] password, byte[] salt, Integer iterations, + Integer keyLength) { + try { + if (PASSWORD_SCHEME_SHA.equals(passwordScheme)) { + MessageDigest digest = MessageDigest.getInstance("SHA1"); + byte[] bytes = charsToBytes(password); + digest.update(bytes); + return digest.digest(); + } else if (PASSWORD_SCHEME_PBKDF2_SHA256.equals(passwordScheme)) { + KeySpec spec = new PBEKeySpec(password, salt, iterations, keyLength); + + SecretKeyFactory f = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA256"); + final int ITERATION_LENGTH = 4; + byte[] key = f.generateSecret(spec).getEncoded(); + byte[] result = new byte[ITERATION_LENGTH + salt.length + key.length]; + byte iterationsArr[] = new BigInteger(iterations.toString()).toByteArray(); + if (iterationsArr.length < ITERATION_LENGTH) { + Arrays.fill(result, 0, ITERATION_LENGTH - iterationsArr.length, (byte) 0); + System.arraycopy(iterationsArr, 0, result, ITERATION_LENGTH - iterationsArr.length, + iterationsArr.length); + } else { + System.arraycopy(iterationsArr, 0, result, 0, ITERATION_LENGTH); + } + System.arraycopy(salt, 0, result, ITERATION_LENGTH, salt.length); + System.arraycopy(key, 0, result, ITERATION_LENGTH + salt.length, key.length); + return result; + } else { + throw new UnsupportedOperationException("Unkown password scheme " + passwordScheme); + } + } catch (Exception e) { + throw new UserDirectoryException("Cannot digest", e); + } + } + static char[] bytesToChars(Object obj) { if (obj instanceof char[]) return (char[]) obj;