2

我需要加密一个字符串然后解密。加密函数运行良好,但是当我将加密值传递给解密函数时,我收到一个空指针异常。如果我在 Java 应用程序中使用相同的代码,则一切正常。

public class Cripthografy {
private static String TAG="freeliberomail";

 public static String encrypt(String seed, String cleartext){
   byte[] rawKey;
   byte[] result=null;
 try {
rawKey = getRawKey(seed.getBytes());

     result = encrypt(rawKey, cleartext.getBytes());
  } catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
  }
   return toHex(result);
  }

  public static String decrypt(String seed, String encrypted) {
    byte[] rawKey;
    byte[] result=null;
   try {
rawKey = getRawKey(seed.getBytes());

    byte[] enc = toByte(encrypted);
    result = decrypt(rawKey, enc);
    } catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
   }
    return new String(result);
   }


   private static byte[] getRawKey(byte[] seed) throws Exception {
      KeyGenerator kgen = KeyGenerator.getInstance("AES");
      SecureRandom sr = SecureRandom.getInstance("SHA1PRNG");
      sr.setSeed(seed);
      kgen.init(128, sr); // 192 and 256 bits may not be available
      SecretKey skey = kgen.generateKey();
      byte[] raw = skey.getEncoded();
      return raw;
    }
    private static byte[] encrypt(byte[] raw, byte[] clear){
 byte[] encrypted=null;
      SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES");
      Cipher cipher;
     try {
 cipher = Cipher.getInstance("AES");
     cipher.init(Cipher.ENCRYPT_MODE, skeySpec);
     encrypted = cipher.doFinal(clear);
     } catch (NoSuchAlgorithmException e) {
// TODO Auto-generated catch block
e.printStackTrace();
    } catch (NoSuchPaddingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
    } catch (InvalidKeyException e) {
// TODO Auto-generated catch block
e.printStackTrace();
    } catch (IllegalBlockSizeException e) {
// TODO Auto-generated catch block
e.printStackTrace();
    } catch (BadPaddingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
    }
     return encrypted;
    }


     private static byte[] decrypt(byte[] raw, byte[] encrypted) {
 byte[] decrypted = null;
     SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES");
     Cipher cipher;
     try {
 cipher = Cipher.getInstance("AES");
     cipher.init(Cipher.DECRYPT_MODE, skeySpec);
     decrypted = cipher.doFinal(encrypted);
     }catch (NoSuchAlgorithmException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
      } catch (NoSuchPaddingException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
      } catch (InvalidKeyException e) {
// TODO Auto-generated catch block
e.printStackTrace(); 
     } catch (IllegalBlockSizeException e) {
// TODO Auto-generated catch block
e.printStackTrace();
   } catch (BadPaddingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
   }

    return decrypted;
   }


  public static String toHex(String txt) {
  return toHex(txt.getBytes());
  }

 public static String fromHex(String hex) {
 return new String(toByte(hex));
 }

 public static byte[] toByte(String hexString) {
  int len = hexString.length()/2;
  byte[] result = new byte[len];
  for (int i = 0; i < len; i++)
  result[i] = Integer.valueOf(hexString.substring(2*i, 2*i+2), 16).byteValue();
  return result;
 }


  public static String toHex(byte[] buf) {
    if (buf == null)
    return "";
    StringBuffer result = new StringBuffer(2*buf.length);
      for (int i = 0; i < buf.length; i++) {
        appendHex(result, buf[i]);
    }
     return result.toString();
   }
  private final static String HEX = "0123456789ABCDEF";
  private static void appendHex(StringBuffer sb, byte b) {
  sb.append(HEX.charAt((b>>4)&0x0f)).append(HEX.charAt(b&0x0f));
  }

}

然后我打电话:

          String encValue=Cripthografy.encrypt("MY_KEY", "helloworld");
      String decValue=Cripthografy.decrypt("MY_KEY",  encValue);
      Log.d(TAG,"encript:"+encValue+" "+"decript:"+decValue);

例外是:

      01-17 03:57:23.986: W/System.err(29846): javax.crypto.BadPaddingException: pad      block corrupted
       01-17 03:57:23.991: W/System.err(29846):     at      com.android.org.bouncycastle.jcajce.provider.symmetric.util.BaseBlockCipher.engineDoFinal(B           aseBlockCipher.java:709)
       01-17 03:57:23.991: W/System.err(29846):     at       javax.crypto.Cipher.doFinal(Cipher.java:1111)
        01-17 03:57:23.991: W/System.err(29846):    at    marvellous.freeliberomail.Cripthografy.decrypt(Cripthografy.java:111)
        01-17 03:57:23.991: W/System.err(29846):    at   marvellous.freeliberomail.Cripthografy.decrypt(Cripthografy.java:55)
         01-17 03:57:23.991: W/System.err(29846):   at   marvellous.freeliberomail.Auth.writeCookieTofile(Auth.java:307)
        01-17 03:57:23.991: W/System.err(29846):    at marvellous.freeliberomail.Auth.createSessionCookie(Auth.java:287)
        01-17 03:57:23.991: W/System.err(29846):    at marvellous.freeliberomail.Auth.scenario(Auth.java:196)
        01-17 03:57:23.991: W/System.err(29846):    at marvellous.freeliberomail.Auth.accessMail(Auth.java:117)
        01-17 03:57:23.991: W/System.err(29846):    at marvellous.freeliberomail.Auth.run(Auth.java:96)
       01-17 03:57:23.991: W/System.err(29846):     at java.lang.Thread.run(Thread.java:856)
        01-17 03:57:23.996: W/dalvikvm(29846): threadid=11: thread exiting with uncaught exception (group=0x41584930)
            01-17 03:57:23.996: E/AndroidRuntime(29846): FATAL EXCEPTION: Thread-32785
            01-17 03:57:23.996: E/AndroidRuntime(29846): java.lang.NullPointerException
            01-17 03:57:23.996: E/AndroidRuntime(29846):    at java.lang.String.<init>(String.java:141)
            01-17 03:57:23.996: E/AndroidRuntime(29846):    at marvellous.freeliberomail.Cripthografy.decrypt(Cripthografy.java:60)
            01-17 03:57:23.996: E/AndroidRuntime(29846):    at marvellous.freeliberomail.Auth.writeCookieTofile(Auth.java:307)
             01-17 03:57:23.996: E/AndroidRuntime(29846):   at marvellous.freeliberomail.Auth.createSessionCookie(Auth.java:287)
            01-17 03:57:23.996: E/AndroidRuntime(29846):    at marvellous.freeliberomail.Auth.scenario(Auth.java:196)
            01-17 03:57:23.996: E/AndroidRuntime(29846):    at marvellous.freeliberomail.Auth.accessMail(Auth.java:117)
             01-17 03:57:23.996: E/AndroidRuntime(29846):   at marvellous.freeliberomail.Auth.run(Auth.java:96)
            01-17 03:57:23.996: E/AndroidRuntime(29846):    at java.lang.Thread.run(Thread.java:856)
4

1 回答 1

2

yes, android Cipher does have some issues. One is that the byte[] in cipher.doFinal(encrypted) sometimes has to have the correct length. Try feeding it with an encrypted array of 128 bit (fill up with 0's?)

after many painful hours this example finally works:

private static byte[] key = "12345678".getBytes();// 64 bit 
private static byte[] iv = "12345678".getBytes();

public static String encrypt(String in) {
    String cypert = in;
    try {
        IvParameterSpec ivSpec = new IvParameterSpec(iv);
        SecretKeySpec k = new SecretKeySpec(key, "DES");
        Cipher c = Cipher.getInstance("DES/CBC/PKCS7Padding");
        c.init(Cipher.ENCRYPT_MODE, k, ivSpec);
        byte[] encryptedData = c.doFinal(in.getBytes());
        cypert = Base64.encodeLines(encryptedData);
    } catch (Exception e) {
        Debugger.error(e);
    }
    return cypert;
}


public static String decrypt(String in) throws Exception {
    String plain=in;
    try {
        IvParameterSpec ivSpec = new IvParameterSpec(iv);
        SecretKeySpec keys = new SecretKeySpec(key, "DES");
        Cipher cipher = Cipher.getInstance("DES/CBC/PKCS7Padding");
        cipher.init(Cipher.DECRYPT_MODE, keys, ivSpec);
        // decryption pass
        byte[] cipherText = Base64.decodeLines(in);
        int ctLength = cipherText.length;
        byte[] plainText = new byte[cipher.getOutputSize(ctLength)];
        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        bos.write(cipher.doFinal(cipherText));
        plainText = bos.toByteArray();
        bos.close();
        plain = new String(plainText, "UTF8");
    } catch (Exception e) {
        Debugger.error(e);
    }
    return plain;
}
于 2013-01-23T22:27:42.060 回答