【问题标题】:Android rc4 encryptionAndroid rc4 加密
【发布时间】:2017-06-13 15:37:37
【问题描述】:

我想我遗漏了一些东西,我相信图像(转换为字节)正在被加密,但在到达客户端时没有被解密。该图像似乎通过了 RSA 签名验证,但不知何故无法查看。

客户端代码:

    public void aliceEncrypt(byte[] plaintext, byte[] sharedSecret) {

    Cipher cipher;
    byte[] encrypted = null;
    try {
        cipher = Cipher.getInstance("RC4");
        Key sk = new SecretKeySpec(sharedSecret, "RC4");
        cipher.init(Cipher.ENCRYPT_MODE, sk);
        encrypted = cipher.doFinal(plaintext);
        CipherOutputStream cos = new CipherOutputStream(socket.getOutputStream(), cipher);
        ObjectOutputStream oos = new ObjectOutputStream(cos);
        oos.writeObject(encrypted);
        oos.flush();

    } catch (NoSuchAlgorithmException | NoSuchPaddingException | IOException | InvalidKeyException e) {
        e.printStackTrace();
    } catch (BadPaddingException e) {
        e.printStackTrace();
    } catch (IllegalBlockSizeException e) {
        e.printStackTrace();
    }
}

服务器端代码:

public byte[] bobDecrypt( byte[] sharedSecret) {


    Cipher cipher = null;
    byte[] bytes = null;
    byte[] decrypted = null;
    try {
        cipher = Cipher.getInstance("RC4");
        Key sk = new SecretKeySpec(sharedSecret, "RC4");
        cipher.init(Cipher.DECRYPT_MODE, sk);
        CipherInputStream cis = new CipherInputStream(socket.getInputStream(), cipher);
        ObjectInputStream ois = new ObjectInputStream(cis);
        bytes =  (byte[])ois.readObject();
        decrypted = cipher.doFinal(bytes);

    } catch (NoSuchAlgorithmException | NoSuchPaddingException | IOException | InvalidKeyException | ClassNotFoundException e) {
        e.printStackTrace();
    } catch (BadPaddingException e) {
        e.printStackTrace();
    } catch (IllegalBlockSizeException e) {
        e.printStackTrace();
    }
    return decrypted;
}

【问题讨论】:

  • 我认为 RC4 不存在这些,如果我错了,请纠正我。 RC4 是流密码,不需要填充。
  • 我没听明白,你是在建议我删除 cipher.doFinal()?数据还会被加密吗?
  • 好的,你解决了我的困惑,它正在工作,谢谢队友。我不确定是否可以省略 cipher.doFinal。你可以组织你的答案,我会接受的。

标签: android encryption rc4-cipher


【解决方案1】:

CipherInputStreamCipherOutputStream 旨在完成所有繁重的工作,因此您只需为它们提供一个初始化的Cipher 实例,然后使用写入和读取流方法。在大多数情况下,您可以将它们分层,没有输入和输出流,但有一个微妙之处:当使用分组密码时,没有好的方法可以向 CipherOutputStream 发出它需要调用Cipher.doFinal() 的信号。唯一受支持的方法是调用close() 方法。这些close() 调用传播 到其他包装的流,在这种情况下,套接字输出流被包装,它最终会关闭套接字作为副作用。这可能是完全可以接受的行为,但您需要意识到这一点。在这种情况下,因为您使用的是面向字节的流密码 (RC4),所以没有填充,所以 Cipher.doFinal() 基本上是一个无操作(好吧,它确实重置了密码状态),所以调用 flush()就像打电话给close()一样好。下面的代码基本上是修改后的代码,以正确显示如何分层和使用各种流。

public void aliceEncrypt(byte[] plaintext, byte[] sharedSecret, Socket socket) {

    try {
        Cipher cipher = Cipher.getInstance("RC4/ECB/NoPadding");
        Key sk = new SecretKeySpec(sharedSecret, "RC4");
        cipher.init(Cipher.ENCRYPT_MODE, sk);
        CipherOutputStream cos = new CipherOutputStream(socket.getOutputStream(), cipher);
        ObjectOutputStream oos = new ObjectOutputStream(cos);
        oos.writeObject(plaintext);
        oos.close();

    } catch (Exception e) {
        e.printStackTrace();
    }
}


public byte[] bobDecrypt( byte[] sharedSecret, Socket socket) {


    try {
        Cipher cipher = Cipher.getInstance("RC4/ECB/NoPadding");
        Key sk = new SecretKeySpec(sharedSecret, "RC4");
        cipher.init(Cipher.DECRYPT_MODE, sk);
        CipherInputStream cis = new CipherInputStream(socket.getInputStream(), cipher);
        ObjectInputStream ois = new ObjectInputStream(cis);
        byte[] bytes = (byte[]) ois.readObject();
        return bytes;

    } catch (Exception e) {
        e.printStackTrace();
        return null;
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-12-27
    • 1970-01-01
    • 1970-01-01
    • 2020-12-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多