将byte [] PBEKeySpec存储到openshift齿轮的行为有何不同?

时间:2014-10-01 19:39:54

标签: postgresql security byte openshift


如果有人可以给出一些指示: 我有一个由PBEKeySpec生成的KeySpec:

KeySpec spec = new PBEKeySpec(password.toCharArray(), "SALTSALT".getBytes(), 20000, 160);
SecretKeyFactory f = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1");
byte[] encoded = f.generateSecret(spec).getEncoded();

编码的byte []变量存储在Postgres DB 9.x上,测试环境中的这个值工作得很好,但是当我将它部署到OpenShift时,PBEKeySpec生成的byte []不会返回相同的值(它应该),与我存储在DB上的值相比,编码问题可能吗?任何线索?

来自相同密码的对应日志: 另一件事,OS上的byte []将大小从20改为39

Test environment, passwd stored on DB: [-87, 98, 56, 51,55, 99, 99, 100, 53, 56, 57, 52, 51, 54, 101, 100, 50, 98, 51, 51, 57, 100, 98, 54, 99, 51, 98, 56, 102, 50, 99, 50, 50, 98, 51, 51, 49, 57, 49] size 39
OpenShift gear, password from login: [-117, -12, -115, -38, -58, -100, -62, 70, -87, 98, -73, 114, -56, 115, -91, 5, 23, 44, 119, 21] size: 20

完整代码:

public abstract class PasswordServiceImpl implements PasswordByteService {

private String ENCRIPT_ALGORITHM = "PBKDF2WithHmacSHA1";
private int ENCRYPT_DEVIRED_KEY_LENGTH = 160;
private int ENCRIPT_ITERATIONS = 20000;
private String SALT_ALGORITHM = "SHA1PRNG";


@Override
    public boolean authenticate(final String attemptedPassword, final byte[] encryptedPassword, final byte[] salt)
        throws NoSuchAlgorithmException, InvalidKeySpecException {

    byte[] encryptedAttemptedPassword = getEncryptedPassword(attemptedPassword, salt);

    return Arrays.equals(encryptedPassword, encryptedAttemptedPassword);
}


@Override
public byte[] getEncryptedPassword(final String password, byte[] salt)
        throws NoSuchAlgorithmException, InvalidKeySpecException {

    String algorithm = ENCRIPT_ALGORITHM;
    int derivedKeyLength = ENCRYPT_DEVIRED_KEY_LENGTH;
    int iterations = ENCRIPT_ITERATIONS;

    KeySpec spec = new PBEKeySpec(password.toCharArray(), salt, iterations, derivedKeyLength);

    SecretKeyFactory f = SecretKeyFactory.getInstance(algorithm);
    byte[] encoded = f.generateSecret(spec).getEncoded();


    return encoded;
}


@Override
public byte[] generateSalt() throws NoSuchAlgorithmException, NoSuchProviderException {
    SecureRandom random;
        random = SecureRandom.getInstance(SALT_ALGORITHM,"SUN");

    byte[] salt = new byte[8];
    random.nextBytes(salt);

    return salt;
}

}

通过entityManager存储用户,休眠。 实体

@Entity
public class UserData implements Serializable {

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;

...

@Basic(optional = false)
@Column
private byte[] password;


...

配置类

@Stateless
public class ConfigurationBean implements Configuration {
...
@PersistenceContext(unitName = "primary")
private EntityManager em;
...

private void populateFailSafeUser(){

        try {
            PasswordService pws = new PasswordServiceImpl();
            byte[] salt = pws.generateSalt();
            byte[] encryptedPassword = pws.getEncryptedPassword(Values.FAILSAFE_USER_PASS, salt);

            UserData failsafeUser = new UserData(Values.FAILSAFE_USER_NAME, encryptedPassword, salt );

            em.persist(failsafeUser);
            em.flush();
        } catch (NoSuchAlgorithmException | InvalidKeySpecException ex) {
            LOGGER.error(Msg.ERROR_ENCRIPTION_SERVICES);
        } catch (NoSuchProviderException ex) {
            LOGGER.error(Msg.ERROR_ENCRIPTION_SERVICES + " proveedor de seguridad no encontrado!");
    }

}

1 个答案:

答案 0 :(得分:0)

根据您发布的代码,您似乎并未将盐存储在数据库中。您需要存储加密密码时使用的生成的盐。然后,在验证用户输入的密码时,需要使用数据库中的相同盐。

<强>更新 如果您确实在生成原始加密密码和生成尝试密码以进行身份​​验证时使用完全相同的盐,并从f.generateSecret(spec)获取不同的值,那么我最好的猜测是,有某种OpenShift上的错误。特别是如果它在本地使用完全相同的代码。

我建议尽可能少地重现问题,并使用OpenShift opening a bug report。试着让Postgres离开它;如果你确定你从Postgres那里得到的东西和你原来的东西一样,那么它不是问题的一部分。