2010-09-20 41 views
5

我正在用java加密文件並將加密文件和私鑰發送到android設備。但是,在Android中解密文件時,會導致填充塊錯誤。 順便說一句,相同的解密代碼,適用於PC在解密期間損壞的填充塊(Android)

這裏是加密:

public void encrypt(File inf, File outf, File publicKey, int userId, int resourceId) throws ArServerConnectionException { 
    // ENCRYPTION BEGIN 
    try { 
     pkCipher = Cipher.getInstance("RSA"); 
    } catch (NoSuchAlgorithmException e) { 
     // TODO Auto-generated catch block 
     e.printStackTrace(); 
    } catch (NoSuchPaddingException e) { 
     // TODO Auto-generated catch block 
     e.printStackTrace(); 
    } 
    // create AES shared key cipher 
    try { 
     aesCipher = Cipher.getInstance("AES"); 
    } catch (NoSuchAlgorithmException e) { 
     // TODO Auto-generated catch block 
     e.printStackTrace(); 
    } catch (NoSuchPaddingException e) { 
     // TODO Auto-generated catch block 
     e.printStackTrace(); 
    } 

    try { 
     makeKey(); 
    } catch (NoSuchAlgorithmException e) { 
     // TODO Auto-generated catch block 
     e.printStackTrace(); 
    } 
      // File operation 

      try { 
     saveKey(new File(System.getProperty("user.home") + "/" + userId 
       + "/keyfile"), publicKey); 
    } catch (IOException e) { 
     // TODO Auto-generated catch block 
     e.printStackTrace(); 
    } catch (GeneralSecurityException e) { 
     // TODO Auto-generated catch block 
     e.printStackTrace(); 
    } 
    // File operation 

    try { 
     encryptFiles(inf, outf); 
    } catch (InvalidKeyException e) { 
     // TODO Auto-generated catch block 
     e.printStackTrace(); 
    } catch (IOException e) { 
     // TODO Auto-generated catch block 
     e.printStackTrace(); 
    } 

    // /ENCRYPTION END 
} 

    public void saveKey(File out, File publicKeyFile) throws IOException, 
     GeneralSecurityException { 
    // read public key to be used to encrypt the AES key 
    byte[] encodedKey = new byte[(int) publicKeyFile.length()]; 
    new FileInputStream(publicKeyFile).read(encodedKey); 

    // create public key 
    X509EncodedKeySpec publicKeySpec = new X509EncodedKeySpec(encodedKey); 
    KeyFactory kf = KeyFactory.getInstance("RSA"); 
    PublicKey pk = kf.generatePublic(publicKeySpec); 

    // write AES key 
    pkCipher.init(Cipher.ENCRYPT_MODE, pk); 
    CipherOutputStream os = new CipherOutputStream(
      new FileOutputStream(out), pkCipher); 
    os.write(aesKey); 
    os.close(); 
} 
    public void makeKey() throws NoSuchAlgorithmException { 
    KeyGenerator kgen = KeyGenerator.getInstance("AES"); 
    kgen.init(AES_Key_Size); 
    SecretKey key = kgen.generateKey(); 
    aesKey = key.getEncoded(); 
    aeskeySpec = new SecretKeySpec(aesKey, "AES"); 
} 

這裏是解密部分:

public class FileDecrypt { 
    public static final int AES_Key_Size = 256; 

    Cipher pkCipher, aesCipher; 
    byte[] aesKey; 
    SecretKeySpec aeskeySpec; 
    private String pubKeyPath=null; 
    private String prvKeyPath=null; 
    private String keyFilePath=null; 
    private String encFilePath=null; 
    private String unencFilePath=null; 


    public String getEncFilePath() { 
     return encFilePath; 
    } 

    public void setEncFilePath(String encFilePath) { 
     this.encFilePath = encFilePath; 
    } 

    public String getUnencFilePath() { 
     return unencFilePath; 
    } 

    public void setUnencFilePath(String unencFilePath) { 
     this.unencFilePath = unencFilePath; 
    } 

    public String getPubKeyPath() { 
     return pubKeyPath; 
    } 

    public void setPubKeyPath(String pubKeyPath) { 
     this.pubKeyPath = pubKeyPath; 
    } 

    public String getPrvKeyPath() { 
     return prvKeyPath; 
    } 

    public void setPrvKeyPath(String prvKeyPath) { 
     this.prvKeyPath = prvKeyPath; 
    } 

    public String getKeyFilePath() { 
     return keyFilePath; 
    } 

    public void setKeyFilePath(String keyFilePath) { 
     this.keyFilePath = keyFilePath; 
    } 
    public void decrypt() { 
     Log.i("DECRYPT","**************************************************DECRYPT&*******************"); 
     Log.i("encFilePath",encFilePath); 
     Log.i("pubKeyPath",pubKeyPath); 
     Log.i("prvKeyPath",prvKeyPath); 
     Log.i("keyFilePath",keyFilePath); 
     Log.i("unencFilePath",unencFilePath); 
     Log.i("DECRYPT","********************************************DECRYPT&*******************"); 
     try { 
      pkCipher = Cipher.getInstance("RSA"); 
     } catch (NoSuchAlgorithmException e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
     } catch (NoSuchPaddingException e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
     } 
     try { 
      aesCipher = Cipher.getInstance("AES"); 
     } catch (NoSuchAlgorithmException e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
     } catch (NoSuchPaddingException e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
     } 
     //DECRYPTION BEGIN 

     File pkf=new File(pubKeyPath); 
     byte[] encodedKey = new byte[(int) pkf.length()]; 
     try { 
      new FileInputStream(pkf).read(encodedKey); 
      // create public key 
      X509EncodedKeySpec publicKeySpec = new X509EncodedKeySpec(encodedKey); 
      KeyFactory kf = KeyFactory.getInstance("RSA"); 
      PublicKey pk = kf.generatePublic(publicKeySpec); 

      // write AES key 
      pkCipher.init(Cipher.ENCRYPT_MODE, pk); 
     } catch (FileNotFoundException e1) { 
      // TODO Auto-generated catch block 
      e1.printStackTrace(); 
     } catch (IOException e1) { 
      // TODO Auto-generated catch block 
      e1.printStackTrace(); 
     } catch (NoSuchAlgorithmException e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
     } catch (InvalidKeyException e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
     } catch (InvalidKeySpecException e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
     } 
     try { 
      loadKey(new File(keyFilePath), new File(prvKeyPath)); 
     } catch (GeneralSecurityException e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
     } catch (IOException e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
     } 

     try { 
      decrypt(new File(encFilePath), new File(unencFilePath)); 
     } catch (IOException e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
     } 

     //DECRYPTION END 
    } 

    /** 
    * Decrypts an AES key from a file using an RSA private key 
    */ 
    public void loadKey(File in, File privateKeyFile) 
      throws GeneralSecurityException, IOException { 
     // read private key to be used to decrypt the AES key 
     byte[] encodedKey = new byte[(int) privateKeyFile.length()]; 
     new FileInputStream(privateKeyFile).read(encodedKey); 

     // create private key 
     PKCS8EncodedKeySpec privateKeySpec = new PKCS8EncodedKeySpec(encodedKey); 
     KeyFactory kf = KeyFactory.getInstance("RSA"); 
     PrivateKey pk = kf.generatePrivate(privateKeySpec); 

     // read AES key 
     pkCipher.init(Cipher.DECRYPT_MODE, pk); 
     aesKey = new byte[AES_Key_Size/8]; 
     CipherInputStream is = new CipherInputStream(new FileInputStream(in), 
       pkCipher); 
     is.read(aesKey); 
     aeskeySpec = new SecretKeySpec(aesKey, "AES"); 
    } 

    /** 
    * Decrypts and then copies the contents of a given file. 
    */ 
    public void decrypt(File in, File out) throws IOException 
     { 
     try { 
      aesCipher.init(Cipher.DECRYPT_MODE, aeskeySpec); 
     } catch (InvalidKeyException e) { 
      Log.i("EXCEPTION","INVALID KEY EXCEPTION"); 
      e.printStackTrace(); 
     } 

     CipherInputStream is = new CipherInputStream(new FileInputStream(in), 
       aesCipher); 
     FileOutputStream os = new FileOutputStream(out); 

     copy(is, os); 

     is.close(); 
     os.close(); 
    } 

    /** 
    * Copies a stream. 
    */ 
    private void copy(InputStream is, OutputStream os) throws IOException { 
     int i; 
     byte[] b = new byte[2048]; 
     while ((i = is.read(b)) != -1) { 
      os.write(b, 0, i); 
     } 
    } 
} 

回答

4

我們也面臨同樣的問題,它只是在android端(使用android SDK)上做加密部分,然後解密它在設備上解決。沒有其他正確的理由被發現的問題..

+0

Yeap,我們已經完全按照您的說法解決了問題。 – 2011-11-12 03:39:02

0

最可能的原因是你的代碼正在使用將文件發送到設備是不正確的。也許它正在截斷,填充或以其他方式破壞數據,因此它不能正確解密。嘗試使用靜態文件進行測試,看看是否可以找出問題。

+1

我越來越從設備中的文件,並在我的電腦測試它,它正確地解密。因此,它讓我覺得轉移文件沒有問題 – 2010-09-20 10:14:16

0

您正在加密文件的PC使用不同的安全提供商(主要是SunJCE)和Android使用安全提供商「BC」(4.2之前的Bouncy城​​堡,AndroidOpenssl之後4.2)解密文件。因此解密在Android設備上不成功。請從這個位置使用與您的PC類型相對應的充氣城堡瓶子Bouncy castle jar download

使用PC中java代碼中的提供程序「BC」進行加密。

Cipher cipher = Cipher.getInstance("AES", "BC"); 

Decyption將正常工作,在機器人側:)