【问题标题】:strings comparing for the secret key in encryption and decryption android在加密和解密android中比较密钥的字符串
【发布时间】:2014-01-17 15:27:52
【问题描述】:

我正在使用此代码加密和解密文本

public class Encryption {
private static String charsetName = "UTF8";
private static String algorithm = "DES";
private static int base64Mode = Base64.DEFAULT;

public String getCharsetName() {
    return charsetName;
}

public void setCharsetName(String charsetName) {
    this.charsetName = charsetName;
}

public String getAlgorithm() {
    return algorithm;
}

public void setAlgorithm(String algorithm) {
    this.algorithm = algorithm;
}

public int getBase64Mode() {
    return base64Mode;
}

public void setBase64Mode(int base64Mode) {
    this.base64Mode = base64Mode;
}

public static String encrypt(String key, String data) {
    if (key == null || data == null)
        return null;
    try {
        DESKeySpec desKeySpec = new DESKeySpec(key.getBytes(charsetName));
        SecretKeyFactory secretKeyFactory = SecretKeyFactory.getInstance(algorithm);
        SecretKey secretKey = secretKeyFactory.generateSecret(desKeySpec);
        byte[] dataBytes = data.getBytes(charsetName);
        Cipher cipher = Cipher.getInstance(algorithm);
        cipher.init(Cipher.ENCRYPT_MODE, secretKey);
        return Base64.encodeToString(cipher.doFinal(dataBytes), base64Mode);
    } catch (Exception e) {
        return null;
    }
}

public static String decrypt(String key, String data) {
    if (key == null || data == null)
        return null;
    try {
        byte[] dataBytes = Base64.decode(data, base64Mode);
        DESKeySpec desKeySpec = new DESKeySpec(key.getBytes(charsetName));
        SecretKeyFactory secretKeyFactory = SecretKeyFactory.getInstance(algorithm);
        SecretKey secretKey = secretKeyFactory.generateSecret(desKeySpec);
        Cipher cipher = Cipher.getInstance(algorithm);
        cipher.init(Cipher.DECRYPT_MODE, secretKey);
        byte[] dataBytesDecrypted = (cipher.doFinal(dataBytes));
        return new String(dataBytesDecrypted);
    } catch (Exception e) {
        return null;
    }
}

}   

我正在尝试匹配我为加密和解密之前放置的密钥,如果两个密钥都匹配解密文本,否则提示我错误的密钥是我正在尝试做的

string a="sfdsfsjbgdfkbgdfkjbgk";//encrypted text just for assuming 

decrypted=Encryption.decrypt(key, a.trim());

encrypted=Encryption.encrypt(key, decrypted.trim());

if(a.contentEquals(encrypted.trim())){
//show the decrypted text
}

else 
{
//Show the wrong key
}

这就是我想要做的,但是当我输入正确的键时 else 语句会执行 并且应用程序在 if 语句上停止 谁能指出我在这里做错了什么。

【问题讨论】:

  • 您是否尝试过加密和解密相同的密钥并且返回的值相同?
  • 是的,如果我尝试在 else 语句中显示,它会返回相同的值。
  • 查看@Duncan 的答案

标签: android encryption public-key-encryption string-matching


【解决方案1】:

我无法重现您的问题。这是一个小SSCCE 未能证明问题:

注意:如果您提供的代码示例也是 SSCCE,这会更容易

import java.io.UnsupportedEncodingException;
import java.security.GeneralSecurityException;

import android.util.Base64

import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.DESKeySpec;

public class EncryptDecryptTest {

  public static void main(String[] args) throws Exception {
    String key = "12345678";
    String ciphertext = encrypt(key, "foo");

    String decrypted = decrypt(key, ciphertext.trim());
    String encrypted = encrypt(key, decrypted.trim());

    if (ciphertext.contentEquals(encrypted.trim())) {
      System.out.println("decrypted!");
    } else {
      System.out.println("wrong key!");
    }
  }

  public static String encrypt(String key, String data)
      throws GeneralSecurityException, UnsupportedEncodingException {
    DESKeySpec desKeySpec = new DESKeySpec(key.getBytes("UTF8"));
    SecretKeyFactory secretKeyFactory = SecretKeyFactory.getInstance("DES");
    SecretKey secretKey = secretKeyFactory.generateSecret(desKeySpec);
    byte[] dataBytes = data.getBytes("UTF8");
    Cipher cipher = Cipher.getInstance("DES");
    cipher.init(Cipher.ENCRYPT_MODE, secretKey);
    return Base64.encodeToString(cipher.doFinal(dataBytes), Base64.DEFAULT);
  }

  public static String decrypt(String key, String data)
      throws GeneralSecurityException, UnsupportedEncodingException {
    byte[] dataBytes = Base64.decode(data, Base64.DEFAULT);
    DESKeySpec desKeySpec = new DESKeySpec(key.getBytes("UTF8"));
    SecretKeyFactory secretKeyFactory = SecretKeyFactory.getInstance("DES");
    SecretKey secretKey = secretKeyFactory.generateSecret(desKeySpec);
    Cipher cipher = Cipher.getInstance("DES");
    cipher.init(Cipher.DECRYPT_MODE, secretKey);
    byte[] dataBytesDecrypted = (cipher.doFinal(dataBytes));
    return new String(dataBytesDecrypted);
  }    
}

对我来说,这会按预期打印出decrypted!。请注意,我使用标准 Java(不是 Android)进行了测试,但我尝试修复代码以在 Android 上执行。

一些侧面的cmets:

  • 你经常使用trim() 似乎很奇怪。它似乎没有取得任何成果。
  • 当你可以使用equals()时,你使用contentEquals()
  • 您将DES 指定为算法,它将密码模式和填充保留为默认值。你真的应该明确指定这两个。
  • DES 太弱,无法提供任何安全性,因此您可能需要考虑转向更强大的算法。

【讨论】:

  • 如果我插入错误的解密密钥会崩溃,如果我使用的密钥长度小于 8 则会崩溃
  • 我试过这个 `try{ if (ciphertext.equals(encrypted.trim())) { // 显示解密的消息 } else { // 显示错误的密钥 } catch(NullPointerException e){ e.getMessage(); }` 至少这段代码不会在错误的键处崩溃?
  • @OsamaAftab 根据您的密码模式和填充,当您使用错误的密钥解密时可能会出现异常。您必须抓住这些并显示您的“错误密钥”消息。我建议您在使用此功能之前验证密钥大小。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-09-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-14
  • 2012-07-01
相关资源
最近更新 更多