3

每次我使用相同的密码运行设置方法时,每次都会得到不同的密钥结果。我正在使用密钥结果来检查解密密码是否正确,以防止不必要的解密。

我在 java 中运行了以下代码,我没有问题,但在 Android 中它是生成不同密钥的问题。有人可以告诉我问题是什么以及如何解决这个问题。我想有 Android 和 Java 之间的通用软件。

当我在android中运行程序时,我得到了密钥 org.bouncycastle.jce.provider.JCEPBEKEY@12345678

当我在 java 中运行程序时,我得到密钥 com.sun.crypto.Provider.PBEKey@12345678

private static byte[] bytes;
  Cipher ecipher;
  Cipher dcipher;

  // 8-byte Salt
  byte[] salt = {
      (byte)0xA9, (byte)0x9B, (byte)0xC8, (byte)0x32,
      (byte)0x56, (byte)0x35, (byte)0xE3, (byte)0x03
  };

  // Iteration count
  int iterationCount = 19;

  public String setup(String passPhrase) 
  {
      String output = null;
      try {
          // Create the key
          KeySpec keySpec = new PBEKeySpec(passPhrase.toCharArray(), salt, iterationCount);
          SecretKey key = SecretKeyFactory.getInstance(
              "PBEWithMD5AndDES").generateSecret(keySpec);

          ecipher = Cipher.getInstance(key.getAlgorithm());
          dcipher = Cipher.getInstance(key.getAlgorithm());

          // Prepare the parameter to the ciphers
          AlgorithmParameterSpec paramSpec = new PBEParameterSpec(salt, iterationCount);

          // Create the ciphers
          ecipher.init(Cipher.ENCRYPT_MODE, key, paramSpec);
          dcipher.init(Cipher.DECRYPT_MODE, key, paramSpec);

          // print key
          System.out.println("key  = " + key);
          System.out.println("paramSpec  = " + paramSpec);


          output = key.toString();
      //    showToast("setting up key " + output);
      //    showToast("key size " + output.length());
          System.out.println("key Size " + output.length());

      } catch (java.security.InvalidAlgorithmParameterException e) {
      } catch (java.security.spec.InvalidKeySpecException e) {
      } catch (javax.crypto.NoSuchPaddingException e) {
      } catch (java.security.NoSuchAlgorithmException e) {
      } catch (java.security.InvalidKeyException e) {
      }

      return output;
  }
4

3 回答 3

1

而是使用您可以使用的 javax.xml 库

static String byteToHex(byte[] keyBytes) 
{
    StringBuilder sb = new StringBuilder();
    for (byte b : keyBytes) {
        sb.append(String.format("%1$02X", b));
    }

    return sb.toString();
}
于 2012-10-12T07:35:23.017 回答
1

换行:

SecretKey key = SecretKeyFactory.getInstance(
              "PBEWithMD5AndDES").generateSecret(keySpec);

SecretKey key = SecretKeyFactory.getInstance(
              "PBEWithMD5AndDES","BC").generateSecret(keySpec);

像这样,您特别要求加密提供程序(充气城堡)注意:您也必须将 bouncycastle 提供程序添加到您的 VM。

于 2012-10-12T04:26:57.707 回答
1

也许我误解了这个问题,但听起来你想要密钥的实际内容 - 密钥的实际值,作为一个字节序列,它将进行加密。

文本 org.bouncycastle.jce.provider.JCEPBEKEY@12345678 不是密钥的实际值。这只是意味着 JCEPBEKEY 类没有覆盖默认的 toString 实现。要将键的实际值作为字节数组获取,请使用

byte [] keyBytes = key.getEncoded();

[更新/撤回]

在 JVM 上,我将使用以下内容将其打印为十六进制字符串:

String keyString = javax.xml.bind.DatatypeConverter.printHexBinary(keyBytes);

但如前所述,这在 Android 上不可用。@user1024882 的答案看起来像是一种适用于任一平台的好方法。

于 2012-10-12T04:37:32.630 回答