gpt4 book ai didi

android - 解密适用于 IV,即 String.getBytes(),但 SecureRandom.generateSeed() 失败

转载 作者:太空宇宙 更新时间:2023-11-04 03:53:10 24 4
gpt4 key购买 nike

我正在弄清楚如何使用 AES 进行跨平台(Android 和 Python)加密和解密,如果我使用基于 String 的 IV,我似乎可以成功传输数据.但是,如果我立即切换到使用 SecureRandom.generateSeed() 生成的字节,它就会出错。 key 是预先共享的。

工作的 Android 代码(删除了 try/catch block 以保持简短):

String SecretKey = "0123456789abcdef";
String iv = "fedcba9876543210";

IvParameterSpec ivspec = new IvParameterSpec(iv.getBytes());
SecretKeySpec keyspec = new SecretKeySpec(SecretKey.getBytes(), "AES");
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");

//Initialize the cipher
cipher.init(Cipher.ENCRYPT_MODE, keyspec, ivspec);

String message = "What's up?";
byte[] encrypted = cipher.doFinal(message.getBytes());

//Send the data
outputStream.write(encrypted);

有一个小的传输 header ,让客户端知道传入消息的大小,但我认为它不相关,所以我将其遗漏了。接收此消息的 Python 代码如下所示:

#Predefined:
unpad = lambda s : s[0:-ord(s[-1])]

encrypted = cs.recv(messagesize) # Receive the encrypted message
iv = encrypted[:16]

key = AES.new('0123456789abcdef', AES.MODE_CBC,IV=iv)
padded_msg = key.decrypt(encrypted[16:])
decrypted = unpad(padded_msg) #Remove padding

print "read [%s]" % decrypted

结果如下:

read [What's up]

如果我更改 Java 代码中的两行:

SecureRandom rnd = new SecureRandom();
IvParameterSpec ivspec = new IvParameterSpec(rnd.generateSeed(16));

Python 输出变为:

read [?=H��m��lڈ�1ls]

我想知道 SecureRandom 有什么变化?我读到默认情况下 String.getBytes() 返回平台默认编码(对于 Android 4.0),所以我想知道我是否必须在 Python 端对使用 SecureRandom 生成的 IV 进行一些操作。 .?

最佳答案

接收者需要被告知 IV 是什么。查看 this Wikipedia entry 中关于 CBC 的部分:你可以看到一个加密的 n-block 消息由 n+1 个 block 组成,额外的 block 是 IV。没有用于传输它的标准协议(protocol),但我见过的每个代码都是通过在消息前面加上 IV 来实现的,这确实是很自然的事情,并且由于 CBC 的纠错特性,即使代码得到它略有错误。例如,您可以在野外找到使用常量 IV 但在纯文本前面加上随机 block 的代码,这基本上以不同的方式执行相同的操作。有时您甚至会在书中找到这种代码,例如 David Hook 的第 2 章中的 InlineIvCBCExample.java 否则非常好 book .

我推荐使用以下方法进行 AES/CBC/PKCS7Padding:

byte[] plaintext = ...;
byte[] key = ...;

// get iv
SecureRandom rnd = new SecureRandom();
byte[] iv = rnd.getBytes(16);
IvParameterSpec ivSpec = new IvParameterSpec(iv);

// encrypt
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS7Padding");
cipher.init(Cipher.ENCRYPT_MODE, key, ivSpec);
byte[] ciphertext = cipher.doFinal(plaintext);

// copy to result
byte[] result = new byte[iv.length + ciphertext.length];
System.arraycopy(iv, 0, result, 0, iv.length);
System.arraycopy(ciphertext, 0 , result, iv.length, ciphertext.length);

关于android - 解密适用于 IV,即 String.getBytes(),但 SecureRandom.generateSeed() 失败,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20196658/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com