Browse Source

修改:

密码生成类
release
wangxianzhang 4 years ago
parent
commit
bfaed1268e
  1. 61
      epmet-commons/epmet-commons-tools/src/main/java/com/epmet/commons/tools/security/password/BCrypt.java
  2. 2
      epmet-commons/epmet-commons-tools/src/main/java/com/epmet/commons/tools/security/password/BCryptPasswordEncoder.java

61
epmet-commons/epmet-commons-tools/src/main/java/com/epmet/commons/tools/security/password/BCrypt.java

@ -3,7 +3,6 @@ package com.epmet.commons.tools.security.password;
import java.io.ByteArrayOutputStream; import java.io.ByteArrayOutputStream;
import java.io.UnsupportedEncodingException; import java.io.UnsupportedEncodingException;
import java.nio.charset.StandardCharsets;
import java.security.SecureRandom; import java.security.SecureRandom;
/** /**
@ -53,11 +52,11 @@ public class BCrypt {
// Blowfish parameters // Blowfish parameters
private static final int BLOWFISH_NUM_ROUNDS = 16; private static final int BLOWFISH_NUM_ROUNDS = 16;
// Initial contents of key schedule // Initial contents of key schedule
private static final int[] P_orig = { 0x243f6a88, 0x85a308d3, 0x13198a2e, 0x03707344, private static final int P_orig[] = { 0x243f6a88, 0x85a308d3, 0x13198a2e, 0x03707344,
0xa4093822, 0x299f31d0, 0x082efa98, 0xec4e6c89, 0x452821e6, 0x38d01377, 0xa4093822, 0x299f31d0, 0x082efa98, 0xec4e6c89, 0x452821e6, 0x38d01377,
0xbe5466cf, 0x34e90c6c, 0xc0ac29b7, 0xc97c50dd, 0x3f84d5b5, 0xb5470917, 0xbe5466cf, 0x34e90c6c, 0xc0ac29b7, 0xc97c50dd, 0x3f84d5b5, 0xb5470917,
0x9216d5d9, 0x8979fb1b }; 0x9216d5d9, 0x8979fb1b };
private static final int[] S_orig = { 0xd1310ba6, 0x98dfb5ac, 0x2ffd72db, 0xd01adfb7, private static final int S_orig[] = { 0xd1310ba6, 0x98dfb5ac, 0x2ffd72db, 0xd01adfb7,
0xb8e1afed, 0x6a267e96, 0xba7c9045, 0xf12c7f99, 0x24a19947, 0xb3916cf7, 0xb8e1afed, 0x6a267e96, 0xba7c9045, 0xf12c7f99, 0x24a19947, 0xb3916cf7,
0x0801f2e2, 0x858efc16, 0x636920d8, 0x71574e69, 0xa458fea3, 0xf4933d7e, 0x0801f2e2, 0x858efc16, 0x636920d8, 0x71574e69, 0xa458fea3, 0xf4933d7e,
0x0d95748f, 0x728eb658, 0x718bcd58, 0x82154aee, 0x7b54a41d, 0xc25a59b5, 0x0d95748f, 0x728eb658, 0x718bcd58, 0x82154aee, 0x7b54a41d, 0xc25a59b5,
@ -229,16 +228,16 @@ public class BCrypt {
0x1948c25c, 0x02fb8a8c, 0x01c36ae4, 0xd6ebe1f9, 0x90d4f869, 0xa65cdea0, 0x1948c25c, 0x02fb8a8c, 0x01c36ae4, 0xd6ebe1f9, 0x90d4f869, 0xa65cdea0,
0x3f09252d, 0xc208e69f, 0xb74e6132, 0xce77e25b, 0x578fdfe3, 0x3ac372e6 }; 0x3f09252d, 0xc208e69f, 0xb74e6132, 0xce77e25b, 0x578fdfe3, 0x3ac372e6 };
// bcrypt IV: "OrpheanBeholderScryDoubt" // bcrypt IV: "OrpheanBeholderScryDoubt"
static private final int[] bf_crypt_ciphertext = { 0x4f727068, 0x65616e42, static private final int bf_crypt_ciphertext[] = { 0x4f727068, 0x65616e42,
0x65686f6c, 0x64657253, 0x63727944, 0x6f756274 }; 0x65686f6c, 0x64657253, 0x63727944, 0x6f756274 };
// Table for Base64 encoding // Table for Base64 encoding
static private final char[] base64_code = { '.', '/', 'A', 'B', 'C', 'D', 'E', 'F', static private final char base64_code[] = { '.', '/', 'A', 'B', 'C', 'D', 'E', 'F',
'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U',
'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j',
'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y',
'z', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' }; 'z', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' };
// Table for Base64 decoding // Table for Base64 decoding
static private final byte[] index_64 = { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, static private final byte index_64[] = { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 1, 54, 55, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 1, 54, 55,
56, 57, 58, 59, 60, 61, 62, 63, -1, -1, -1, -1, -1, -1, -1, 2, 3, 4, 5, 6, 7, 56, 57, 58, 59, 60, 61, 62, 63, -1, -1, -1, -1, -1, -1, -1, 2, 3, 4, 5, 6, 7,
@ -248,8 +247,8 @@ public class BCrypt {
static final int MIN_LOG_ROUNDS = 4; static final int MIN_LOG_ROUNDS = 4;
static final int MAX_LOG_ROUNDS = 31; static final int MAX_LOG_ROUNDS = 31;
// Expanded Blowfish key // Expanded Blowfish key
private int[] P; private int P[];
private int[] S; private int S[];
/** /**
* Encode a byte array using bcrypt's slightly-modified base64 encoding scheme. Note * Encode a byte array using bcrypt's slightly-modified base64 encoding scheme. Note
@ -261,7 +260,7 @@ public class BCrypt {
* @param rs the destination buffer for the base64-encoded string * @param rs the destination buffer for the base64-encoded string
* @exception IllegalArgumentException if the length is invalid * @exception IllegalArgumentException if the length is invalid
*/ */
static void encode_base64(byte[] d, int len, StringBuilder rs) static void encode_base64(byte d[], int len, StringBuilder rs)
throws IllegalArgumentException { throws IllegalArgumentException {
int off = 0; int off = 0;
int c1, c2; int c1, c2;
@ -360,7 +359,7 @@ public class BCrypt {
* @param lr an array containing the two 32-bit half blocks * @param lr an array containing the two 32-bit half blocks
* @param off the position in the array of the blocks * @param off the position in the array of the blocks
*/ */
private final void encipher(int[] lr, int off) { private final void encipher(int lr[], int off) {
int i, n, l = lr[off], r = lr[off + 1]; int i, n, l = lr[off], r = lr[off + 1];
l ^= P[0]; l ^= P[0];
@ -389,7 +388,7 @@ public class BCrypt {
* @param offp a "pointer" (as a one-entry array) to the current offset into data * @param offp a "pointer" (as a one-entry array) to the current offset into data
* @return the next word of material from data * @return the next word of material from data
*/ */
private static int streamtoword(byte[] data, int[] offp) { private static int streamtoword(byte data[], int offp[]) {
int i; int i;
int word = 0; int word = 0;
int off = offp[0]; int off = offp[0];
@ -407,18 +406,18 @@ public class BCrypt {
* Initialise the Blowfish key schedule * Initialise the Blowfish key schedule
*/ */
private void init_key() { private void init_key() {
P = P_orig.clone(); P = (int[]) P_orig.clone();
S = S_orig.clone(); S = (int[]) S_orig.clone();
} }
/** /**
* Key the Blowfish cipher * Key the Blowfish cipher
* @param key an array containing the key * @param key an array containing the key
*/ */
private void key(byte[] key) { private void key(byte key[]) {
int i; int i;
int[] koffp = { 0 }; int koffp[] = { 0 };
int[] lr = { 0, 0 }; int lr[] = { 0, 0 };
int plen = P.length, slen = S.length; int plen = P.length, slen = S.length;
for (i = 0; i < plen; i++) { for (i = 0; i < plen; i++) {
@ -444,11 +443,10 @@ public class BCrypt {
* @param data salt information * @param data salt information
* @param key password information * @param key password information
*/ */
private void ekskey(byte[] data, byte[] key) { private void ekskey(byte data[], byte key[]) {
int i; int i;
int[] koffp = { 0 }; int koffp[] = { 0 }, doffp[] = { 0 };
int[] doffp = { 0 }; int lr[] = { 0, 0 };
int[] lr = { 0, 0 };
int plen = P.length, slen = S.length; int plen = P.length, slen = S.length;
for (i = 0; i < plen; i++) { for (i = 0; i < plen; i++) {
@ -486,10 +484,10 @@ public class BCrypt {
* @param log_rounds the binary logarithm of the number of rounds of hashing to apply * @param log_rounds the binary logarithm of the number of rounds of hashing to apply
* @return an array containing the binary hashed password * @return an array containing the binary hashed password
*/ */
private byte[] crypt_raw(byte[] password, byte[] salt, int log_rounds) { private byte[] crypt_raw(byte password[], byte salt[], int log_rounds) {
int[] cdata = bf_crypt_ciphertext.clone(); int cdata[] = (int[]) bf_crypt_ciphertext.clone();
int clen = cdata.length; int clen = cdata.length;
byte[] ret; byte ret[];
long rounds = roundsForLogRounds(log_rounds); long rounds = roundsForLogRounds(log_rounds);
@ -526,10 +524,8 @@ public class BCrypt {
public static String hashpw(String password, String salt) throws IllegalArgumentException { public static String hashpw(String password, String salt) throws IllegalArgumentException {
BCrypt B; BCrypt B;
String real_salt; String real_salt;
byte[] passwordb; byte passwordb[], saltb[], hashed[];
byte[] saltb; char minor = (char) 0;
byte[] hashed;
char minor = (char) 0;
int rounds, off = 0; int rounds, off = 0;
StringBuilder rs = new StringBuilder(); StringBuilder rs = new StringBuilder();
@ -568,9 +564,14 @@ public class BCrypt {
rounds = Integer.parseInt(salt.substring(off, off + 2)); rounds = Integer.parseInt(salt.substring(off, off + 2));
real_salt = salt.substring(off + 3, off + 25); real_salt = salt.substring(off + 3, off + 25);
passwordb = (password + (minor >= 'a' ? "\000" : "")).getBytes(StandardCharsets.UTF_8); try {
passwordb = (password + (minor >= 'a' ? "\000" : "")).getBytes("UTF-8");
}
catch (UnsupportedEncodingException uee) {
throw new AssertionError("UTF-8 is not supported");
}
saltb = decode_base64(real_salt, BCRYPT_SALT_LEN); saltb = decode_base64(real_salt, BCRYPT_SALT_LEN);
B = new BCrypt(); B = new BCrypt();
hashed = B.crypt_raw(passwordb, saltb, rounds); hashed = B.crypt_raw(passwordb, saltb, rounds);
@ -602,7 +603,7 @@ public class BCrypt {
throw new IllegalArgumentException("Bad number of rounds"); throw new IllegalArgumentException("Bad number of rounds");
} }
StringBuilder rs = new StringBuilder(); StringBuilder rs = new StringBuilder();
byte[] rnd = new byte[BCRYPT_SALT_LEN]; byte rnd[] = new byte[BCRYPT_SALT_LEN];
random.nextBytes(rnd); random.nextBytes(rnd);

2
epmet-commons/epmet-commons-tools/src/main/java/com/epmet/commons/tools/security/password/BCryptPasswordEncoder.java

@ -65,7 +65,7 @@ public class BCryptPasswordEncoder implements PasswordEncoder {
return BCrypt.hashpw(rawPassword.toString(), salt); return BCrypt.hashpw(rawPassword.toString(), salt);
} }
@Override @Override
public boolean matches(CharSequence rawPassword, String encodedPassword) { public boolean matches(CharSequence rawPassword, String encodedPassword) {
if (encodedPassword == null || encodedPassword.length() == 0) { if (encodedPassword == null || encodedPassword.length() == 0) {
logger.warn("Empty encoded password"); logger.warn("Empty encoded password");

Loading…
Cancel
Save