【问题标题】:Java string encryptJava字符串加密
【发布时间】:2013-04-03 20:59:20
【问题描述】:

我正在为我的 iPhone 应用程序使用 Objective C 中的加密类,但我很难从我的 android 应用程序中获得在 JAVA 中工作的相同功能。我的加密代码如下:

NSString * _secret = @"password";
NSString * _key = @"1428324560542678";

StringEncryption *crypto = [[StringEncryption alloc] init];
NSData *_secretData = [_secret dataUsingEncoding:NSUTF8StringEncoding];
CCOptions padding = kCCOptionPKCS7Padding;
NSData *encryptedData = [crypto encrypt:_secretData key:[_key dataUsingEncoding:NSUTF8StringEncoding] padding:&padding];

我试图在 JAVA 中复制它,但是当我对相同的数据进行编码时,我得到了一个不同的字符串。所以我做错了什么,但我无法弄清楚。这是我的 JAVA 代码:

byte[] key = "1428324560542678".getBytes();

Cipher c = null;
            try {
                c = Cipher.getInstance("AES/ECB/PKCS7Padding");
            } catch (NoSuchAlgorithmException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } catch (NoSuchPaddingException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }

SecretKeySpec k =  new SecretKeySpec(key, "AES");
            try {
                c.init(Cipher.ENCRYPT_MODE, k);
            } catch (InvalidKeyException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }

    try {
        EditText tv1passwordText = (EditText) findViewById(R.id.password);
        String password = URLEncoder.encode(tv1passwordText.getText().toString(), "UTF-8");

            byte[] encryptedData = c.doFinal( password.getBytes());

谁能看出我哪里出错了?

基于下面的 cmets,我添加了 getBytes,但生成的字符串仍然不同:

byte[] key = null;
            try {
                key = "1428324560542678".getBytes("UTF-8");
            } catch (UnsupportedEncodingException e2) {
                // TODO Auto-generated catch block
                e2.printStackTrace();
            }

            Cipher c = null;
            try {
                c = Cipher.getInstance("AES/ECB/PKCS7Padding");
            } catch (NoSuchAlgorithmException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } catch (NoSuchPaddingException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }

            SecretKeySpec k =  new SecretKeySpec(key, "AES");
            try {
                c.init(Cipher.ENCRYPT_MODE, k);
            } catch (InvalidKeyException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }

            try {
                EditText tv1passwordText = (EditText) findViewById(R.id.password);

                byte[] password = tv1passwordText.getText().toString().getBytes("UTF-8");

                byte[] encryptedData = c.doFinal(password);

【问题讨论】:

  • 如果要匹配字符串,需要在getBytes()中指定字符集。

标签: java android ios encryption


【解决方案1】:

如果可能,您应该使用 CBC 或 CTR,而不是使用 ECB。 ECB is insecure.

您的 Objective-C 代码似乎使用 UTF-8 编码,但您没有在 Java 代码中指定这一点。使用getBytes("UTF-8")

【讨论】:

  • 感谢大家的帮助。我没有使用 getBytes,所以我将代码更改为使用 getBytes,但仍然没有运气。
【解决方案2】:

我注意到过去引起问题的一件事是被加密的iOS 字符串实际上是"Hello World\0",例如,要加密的字符串末尾有一个额外的空值。因此,请尝试在 Java 中将 \0 添加到字符串的末尾,看看它是否会产生相同的结果。

此外,java 上的URLEncoder 步骤可能会引入额外的控制字符和其他在 iOS 端不存在的东西。可能值得将之后的文本与进入 iOS 加密步骤的文本进行比较,以确保它们完全相同

【讨论】:

  • 删除了 URL 编码器并按照建议使用了 getBytes 方法,但仍然没有乐趣。
  • 您是否尝试将\0 添加到您从密码字段获取的字符串的末尾?
  • 不高兴,我尝试将 \0 添加到字符串的末尾,但编码的字符串仍然不同
【解决方案3】:

下面是加解密示例:

public static SecretKey generateKey() throws NoSuchAlgorithmException, InvalidKeySpecException {
    return secret = new SecretKeySpec(password.getBytes(), "AES");
}

public static byte[] encryptMsg(String message, SecretKey secret) throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, InvalidParameterSpecException, IllegalBlockSizeException, BadPaddingException, UnsupportedEncodingException {
/* Encrypt the message. */
    Cipher cipher = null;
    cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
    cipher.init(Cipher.ENCRYPT_MODE, secret);
    byte[] cipherText = cipher.doFinal(message.getBytes("UTF-8"));
    return cipherText;
}

public static String decryptMsg(byte[] cipherText, SecretKey secret) throws NoSuchPaddingException, NoSuchAlgorithmException, InvalidParameterSpecException, InvalidAlgorithmParameterException, InvalidKeyException, BadPaddingException, IllegalBlockSizeException, UnsupportedEncodingException {

    /* Decrypt the message, given derived encContentValues and initialization vector. */
    Cipher cipher = null;
    cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
   cipher.init(Cipher.DECRYPT_MODE, secret);
    String decryptString = new String(cipher.doFinal(cipherText), "UTF-8");
    return decryptString;
}

加密:

    SecretKey secret = EncUtil.generateKey();
    EncUtil.encryptMsg(<String to Encrypt>, secret))

解密

    EncUtil.decryptMsg(<byte[]>, secret))

【讨论】:

  • @wangyif2 EncUtil 是什么类?
  • @RyPope,它将是 encryptMsg 方法所在的类(完全取决于您)。
  • 如果我没记错你的代码 sn-p 假设“秘密”也是静态的。如果不是,则必须在 generate 方法中删除 secret =。
  • 您从哪里获得密钥或如何生成密钥?
猜你喜欢
  • 2013-09-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-12-08
  • 1970-01-01
  • 1970-01-01
  • 2018-03-05
  • 2018-05-19
相关资源
最近更新 更多