解密过程中垫块被破坏(Android)

时间:2010-09-20 07:59:22

标签: java android encryption

我正在加密java中的文件,并将加密的文件和私钥发送到Android设备。但是在解密Android中的文件时,它会给pad块损坏错误。 顺便说一下,相同的解密代码可以在PC上运行

以下是加密:

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);
        }
    }
}

3 个答案:

答案 0 :(得分:4)

我们也遇到了同样的问题,它只在android端进行加密部分(使用android SDK),然后在设备上解密时解决了。没有找到该问题的其他正确理由..

答案 1 :(得分:0)

最可能的原因是您用于将文件发送到设备的代码不正确。也许是截断,填充或以其他方式破坏数据,因此它无法正确解密。尝试使用静态文件进行测试,看看是否可以隔离问题。

答案 2 :(得分:0)

您正在加密文件的PC正在使用不同的安全提供程序(主要是SunJCE),而Android使用安全提供程序“BC”(4.2之前的Bouncy Castle,4.2之后的AndroidOpenssl)来解密文件。因此解密在Android设备上不成功。请使用此地点Bouncy castle jar download对应您的PC类型的充气城堡罐。

使用PC中的java代码中的提供程序“BC”进行加密。

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

Decyption在android方面可以正常工作:)