android中的密码加密解密

android中的密码加密解密,android,encryption,passwords,cryptography,Android,Encryption,Passwords,Cryptography,能够加密密码,并将解密相同的密码,但我有一些想法,我不确定这是我第一次尝试加密密码。这样加密密码安全吗?因为我尝试了加密密码:zxc,结果只是一个四个字母的密码(结果是:enhj),所以我想知道加密密码是否安全。关于如何重新编写代码以使其更安全且不易解码,以及如何解密加密密码,有何想法 更新:这是我在上找到的加密和解密示例,但我无法使其运行 加密 String text = name1.getText().toString(); // Sending side byte[] da

能够加密密码,并将解密相同的密码,但我有一些想法,我不确定这是我第一次尝试加密密码。这样加密密码安全吗?因为我尝试了加密密码:
zxc
,结果只是一个四个字母的密码(结果是:
enhj
),所以我想知道加密密码是否安全。关于如何重新编写代码以使其更安全且不易解码,以及如何解密加密密码,有何想法

更新:这是我在上找到的加密和解密示例,但我无法使其运行

加密

String text = name1.getText().toString();
    // Sending side
    byte[] data = null;
    try {
        data = text.getBytes("UTF-8");
    } catch (UnsupportedEncodingException e1) {
    e1.printStackTrace();
    }
    String base64 = Base64.encodeToString(data, Base64.DEFAULT);
解密

String password  = "password";
int iterationCount = 1000;
int keyLength = 256;
int saltLength = keyLength / 8; // same size as key output

SecureRandom random = new SecureRandom();
byte[] salt = new byte[saltLength];
randomb.nextBytes(salt);
KeySpec keySpec = new PBEKeySpec(password.toCharArray(), salt,
                    iterationCount, keyLength);
SecretKeyFactory keyFactory = SecretKeyFactory
                    .getInstance("PBKDF2WithHmacSHA1");
byte[] keyBytes = keyFactory.generateSecret(keySpec).getEncoded();
SecretKey key = new SecretKeySpec(keyBytes, "AES");

Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
byte[] iv = new byte[cipher.getBlockSize());
random.nextBytes(iv);
IvParameterSpec ivParams = new IvParameterSpec(iv);
cipher.init(Cipher.ENCRYPT_MODE, key, ivParams);
byte[] ciphertext = cipher.doFinal(plaintext.getBytes("UTF-8"));

您已经标记了此加密、密码和加密,因此我将照样回答

首先,它并不是真正的加密,它只是编码——本质上从8位字节变为6位字节,您的测试非常完美——3*8位字符=24位。24位/6位=4个Base64字符。我还验证了enhj确实是zxc的Base64编码。为了进一步证明这一点,请注意您没有提供任何加密密钥

第二,对于用户身份验证(我假设您正在这样做),不要加密密码-这是一个主要问题。对于用户身份验证,您永远不需要再次查看用户的密码-您只需要验证他们是否输入了与以前相同的密码。因此,当他们第一次输入密码时,您可以对其进行加密和散列。下一次,您将检索第一次使用的salt,并使用相同的salt(以及#迭代次数/工作系数)对新输入的密码进行散列-如果结果与您记录的结果相同,请让他们加入,因为使用相同的密码将得到相同的结果

三个标准答案是PBKDF2、Bcrypt和Scrypt。出现了一个关于Android密码哈希的快速谷歌搜索:

  • 指的是和/或
  • 指PBKDF2-HMAC-SHA-256的SpongyCastle 1.47+实现以及对PBKDF2-HMAC-SHA-1的引用

    String[] fields = ciphertext.split("]");
    byte[] salt = fromBase64(fields[0]);
    byte[] iv = fromBase64(fields[1]);
    byte[] cipherBytes = fromBase64(fields[2]);
    // as above
    SecretKey key = deriveKeyPbkdf2(salt, password);
    
    Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
    IvParameterSpec ivParams = new IvParameterSpec(iv);
    cipher.init(Cipher.DECRYPT_MODE, key, ivParams);
    byte[] plaintext = cipher.doFinal(cipherBytes);
    String plainrStr = new String(plaintext , "UTF-8");
    
     PKCS5S2ParametersGenerator generator = new PKCS5S2ParametersGenerator(new SHA256Digest());
     generator.init(PBEParametersGenerator.PKCS5PasswordToUTF8Bytes(password), salt, iterations);
     KeyParameter key = (KeyParameter)generator.generateDerivedMacParameters(keySizeInBits);
    
  • 本标准还参考了PBKDF2-HMAC-SHA-1

    String[] fields = ciphertext.split("]");
    byte[] salt = fromBase64(fields[0]);
    byte[] iv = fromBase64(fields[1]);
    byte[] cipherBytes = fromBase64(fields[2]);
    // as above
    SecretKey key = deriveKeyPbkdf2(salt, password);
    
    Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
    IvParameterSpec ivParams = new IvParameterSpec(iv);
    cipher.init(Cipher.DECRYPT_MODE, key, ivParams);
    byte[] plaintext = cipher.doFinal(cipherBytes);
    String plainrStr = new String(plaintext , "UTF-8");
    
     PKCS5S2ParametersGenerator generator = new PKCS5S2ParametersGenerator(new SHA256Digest());
     generator.init(PBEParametersGenerator.PKCS5PasswordToUTF8Bytes(password), salt, iterations);
     KeyParameter key = (KeyParameter)generator.generateDerivedMacParameters(keySizeInBits);
    
    }

在所有情况下,选择尽可能高的迭代计数/工作系数,以承受延迟(尽可能快地为所选算法使用库,以遵守的许可证)。salt应该是8到16字节长度范围内的加密随机字节序列

特别是对于PBKDF2,不要使用比本机哈希大小更多的outputBytes,否则会给攻击者带来相对优势—SHA-1本机大小为20字节,SHA-256为32字节,SHA-512本机大小为64字节


如果您确实需要加密而不是身份验证,上面的“使用加密技术安全地存储凭据”链接也涵盖了这一点,尽管更好的答案是存储salt和迭代次数/工作系数,并且每次只需从密码重新生成密钥—如果数据解密,那就好了。如果不是的话,那么就是错误的密码。

您已经标记了此加密、密码和加密,因此我将照样回答

首先,它并不是真正的加密,它只是编码——本质上从8位字节变为6位字节,您的测试非常完美——3*8位字符=24位。24位/6位=4个Base64字符。我还验证了enhj确实是zxc的Base64编码。为了进一步证明这一点,请注意您没有提供任何加密密钥

第二,对于用户身份验证(我假设您正在这样做),不要加密密码-这是一个主要问题。对于用户身份验证,您永远不需要再次查看用户的密码-您只需要验证他们是否输入了与以前相同的密码。因此,当他们第一次输入密码时,您可以对其进行加密和散列。下一次,您将检索第一次使用的salt,并使用相同的salt(以及#迭代次数/工作系数)对新输入的密码进行散列-如果结果与您记录的结果相同,请让他们加入,因为使用相同的密码将得到相同的结果

三个标准答案是PBKDF2、Bcrypt和Scrypt。出现了一个关于Android密码哈希的快速谷歌搜索:

  • 指的是和/或
  • 指PBKDF2-HMAC-SHA-256的SpongyCastle 1.47+实现以及对PBKDF2-HMAC-SHA-1的引用

    String[] fields = ciphertext.split("]");
    byte[] salt = fromBase64(fields[0]);
    byte[] iv = fromBase64(fields[1]);
    byte[] cipherBytes = fromBase64(fields[2]);
    // as above
    SecretKey key = deriveKeyPbkdf2(salt, password);
    
    Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
    IvParameterSpec ivParams = new IvParameterSpec(iv);
    cipher.init(Cipher.DECRYPT_MODE, key, ivParams);
    byte[] plaintext = cipher.doFinal(cipherBytes);
    String plainrStr = new String(plaintext , "UTF-8");
    
     PKCS5S2ParametersGenerator generator = new PKCS5S2ParametersGenerator(new SHA256Digest());
     generator.init(PBEParametersGenerator.PKCS5PasswordToUTF8Bytes(password), salt, iterations);
     KeyParameter key = (KeyParameter)generator.generateDerivedMacParameters(keySizeInBits);
    
  • 本标准还参考了PBKDF2-HMAC-SHA-1

    String[] fields = ciphertext.split("]");
    byte[] salt = fromBase64(fields[0]);
    byte[] iv = fromBase64(fields[1]);
    byte[] cipherBytes = fromBase64(fields[2]);
    // as above
    SecretKey key = deriveKeyPbkdf2(salt, password);
    
    Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
    IvParameterSpec ivParams = new IvParameterSpec(iv);
    cipher.init(Cipher.DECRYPT_MODE, key, ivParams);
    byte[] plaintext = cipher.doFinal(cipherBytes);
    String plainrStr = new String(plaintext , "UTF-8");
    
     PKCS5S2ParametersGenerator generator = new PKCS5S2ParametersGenerator(new SHA256Digest());
     generator.init(PBEParametersGenerator.PKCS5PasswordToUTF8Bytes(password), salt, iterations);
     KeyParameter key = (KeyParameter)generator.generateDerivedMacParameters(keySizeInBits);
    
    }

在所有情况下,选择尽可能高的迭代计数/工作系数,以承受延迟(尽可能快地为所选算法使用库,以遵守的许可证)。salt应该是8到16字节长度范围内的加密随机字节序列

特别是对于PBKDF2,不要使用比本机哈希大小更多的outputBytes,否则会给攻击者带来相对优势—SHA-1本机大小为20字节,SHA-256为32字节,SHA-512本机大小为64字节


如果您确实需要加密而不是身份验证,上面的“使用加密技术安全地存储凭据”链接也涵盖了这一点,尽管更好的答案是存储salt和迭代次数/工作系数,并且每次只需从密码重新生成密钥—如果数据解密,那就好了。如果不是,那么就是密码错误。

您没有加密任何内容。您正在将字节转换为base64编码。您需要使用加密算法。请参见,您没有加密任何内容。您正在将字节转换为base64编码。您需要使用加密算法。看

哇,你写了这么多。你应该得到+1我会进一步研究你的答案,这样我就可以在我的程序上实现它。关于身份验证的事情你是对的。我认为最好是加密密码,但我甚至没有意识到这不是加密密码。我只是在谷歌上搜索了它,它给了我这个结果,所以我在我的示例项目上尝试了它