我正在尝试使用PyCrypto构建两个函数,它们接受两个参数:消息和密钥,然后加密/解密消息.
我在网上发现了几个链接来帮助我,但每个链接都有缺陷:
在codekoala上的这个使用os.urandom,PyCrypto不鼓励这样做.
而且,我给函数的关键不能保证具有预期的确切长度.我该怎么做才能实现这一目标?
此外,还有几种模式,建议使用哪种模式?我不知道该用什么:/
最后,究竟是什么?我可以为加密和解密提供不同的IV,还是会以不同的结果返回?
这是我到目前为止所做的:
from Crypto import Random
from Crypto.Cipher import AES
import base64
BLOCK_SIZE=32
def encrypt(message, passphrase):
# passphrase MUST be 16, 24 or 32 bytes long, how can I do that ?
IV = Random.new().read(BLOCK_SIZE)
aes = AES.new(passphrase, AES.MODE_CFB, IV)
return base64.b64encode(aes.encrypt(message))
def decrypt(encrypted, passphrase):
IV = Random.new().read(BLOCK_SIZE)
aes = AES.new(passphrase, AES.MODE_CFB, IV)
return aes.decrypt(base64.b64decode(encrypted))
Run Code Online (Sandbox Code Playgroud) 根据我的问题Aes Encryption ...错过了一个重要的部分,我现在已经了解到我在字符串上创建可逆加密的假设有点过时了.我现在有
public static byte[] EncryptString(string toEncrypt, byte[] encryptionKey)
{
var toEncryptBytes = Encoding.UTF8.GetBytes(toEncrypt);
using (var provider = new AesCryptoServiceProvider())
{
provider.Key = encryptionKey;
provider.Mode = CipherMode.CBC;
provider.Padding = PaddingMode.PKCS7;
using (var encryptor = provider.CreateEncryptor(provider.Key, provider.IV))
{
using (var ms = new MemoryStream())
{
using (var cs = new CryptoStream(ms, encryptor, CryptoStreamMode.Write))
{
cs.Write(toEncryptBytes, 0, toEncryptBytes.Length);
cs.FlushFinalBlock();
}
return ms.ToArray();
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
这产生了一致的结果; 但是,如果不知道/设置初始化向量,我将无法解密.我真的不想将三个值传递给这个方法(在IV上),这让我硬编码IV或从密钥中导出它.我想知道这是不是一个好的做法,或者它是否会使加密的值容易受到某种程度的攻击......或者我是否真的过度思考这个并且应该硬编码IV?
更新 根据铱星的建议,我尝试了类似的东西:
public static byte[] EncryptString(string toEncrypt, byte[] encryptionKey)
{
if …Run Code Online (Sandbox Code Playgroud) 我知道独特的IV在加密时非常重要,可以防止频率分析等攻击.问题:对于AES CBC加密,最重要的是IV?有一个非常明确的答案解释了IV的重要性.
以明文形式发送IV会有任何安全漏洞吗?或者是否需要使用用于发送对称密钥的相同公钥/私钥进行加密?
如果需要加密发送IV,那么为什么不每次都生成一个新的对称密钥并将IV视为密钥的一部分?是否生成对称密钥太昂贵了?还是最小化传输的数据量?
Secret与Non-secret Initialization Vector的最佳答案如下:
典型的密钥建立协议将导致双方计算一个数据,但只有他们都知道.利用Diffie-Hellman(或其任何椭圆曲线变体),所述共享数据片段具有固定长度并且它们不能控制其值(它们两者都获得相同的看似随机的比特序列).
两个实体如何在没有共享信息的情况下导出"相同的看似随机的比特序列"?假设共享信息是加密发送的吗?并且,如果共享信息是加密发送的,为什么不直接发送加密的IV?
因为应用程序需要安全地传输对称密钥,所以将IV与密钥本身分开似乎是一种优化.或者我错过了什么?
今天我正在做一些悠闲的阅读,并偶然发现了使用离散对数密码学(修订版)(NIST特刊800-56A)的双智能密钥建立方案建议书第5.8节(第45页).我很困惑:
应使用Approved密钥派生函数(KDF)从共享密钥中导出秘密密钥材料.来自KDF的输出仅用于秘密密钥材料,例如用于数据加密或消息完整性的对称密钥,秘密初始化向量或将用于生成其他密钥的主密钥(可能使用不同的进程) ).不应使用共享密钥生成非秘密密钥材料(例如非秘密初始化向量).
现在我不是Alan Turing,但我认为初始化向量不需要保密.在什么情况下会想要一个"秘密初始化向量?" 托马斯·波尔宁说,IVs是公开的,他似乎精通密码学.与caf一样.
我绝不是一名加密专家,我一直在阅读围绕Stack Overflow和维基百科的一些问题,但在定义IV及其用法方面,没有什么是真正"明确的".
我发现的要点:
我确信还有很多其他要点,有人能想到我错过的任何其他特征吗?
我即将使用以下脚本来加密和解密某些数据.我正在使用它,因为我当前的加密在我们的新服务器上不起作用.我们目前正在使用mcrypt,所以我想更改为openssl.
在我们的数据库中,我们使用aes加密,它使用128位密钥,所以我知道密钥是什么,但我不知道openssl iv是什么?为什么我需要钥匙和iv.
我即将使用的代码就是这个,我在网站上找到了,因为我不太了解加密.
显然我会修改它,以便将密钥保存在其他地方.
function encrypt_decrypt($action, $string) {
$output = false;
$encrypt_method = "AES-256-CBC";
$secret_key = 'This is my secret key';
$secret_iv = 'This is my secret iv';
// hash
$key = hash('sha256', $secret_key);
// iv - encrypt method AES-256-CBC expects 16 bytes - else you will get a warning
$iv = substr(hash('sha256', $secret_iv), 0, 16);
if( $action == 'encrypt' ) {
$output = openssl_encrypt($string, $encrypt_method, $key, 0, $iv);
$output = base64_encode($output);
}
else if( $action == 'decrypt' ){ …Run Code Online (Sandbox Code Playgroud) 我试图了解PyCrypto如何在项目中使用,但我还没有完全理解初始化向量(IV)的重要性.我发现在解码字符串时我可以使用错误的IV,除了前16个字节(块大小)之外我似乎仍然收到消息.我只是错误地使用它或不理解某些东西?
这是一个示例代码,用于演示:
import Crypto
import Crypto.Random
from Crypto.Cipher import AES
def pad_data(data):
if len(data) % 16 == 0:
return data
databytes = bytearray(data)
padding_required = 15 - (len(databytes) % 16)
databytes.extend(b'\x80')
databytes.extend(b'\x00' * padding_required)
return bytes(databytes)
def unpad_data(data):
if not data:
return data
data = data.rstrip(b'\x00')
if data[-1] == 128: # b'\x80'[0]:
return data[:-1]
else:
return data
def generate_aes_key():
rnd = Crypto.Random.OSRNG.posix.new().read(AES.block_size)
return rnd
def encrypt(key, iv, data):
aes = AES.new(key, AES.MODE_CBC, iv)
data = pad_data(data)
return aes.encrypt(data)
def decrypt(key, …Run Code Online (Sandbox Code Playgroud) 我正在为Android中的PBE实现和AES加密引擎,我发现了两种方法来实现IV的创建,我想知道哪一个更好,更安全得到IvParameterSpec:
方法#1:
SecureRandom randomSecureRandom = SecureRandom.getInstance("SHA1PRNG");
byte[] iv = new byte[cipher.getBlockSize()];
randomSecureRandom.nextBytes(iv);
IvParameterSpec ivParams = new IvParameterSpec(iv);
Run Code Online (Sandbox Code Playgroud)
方法#2:
AlgorithmParameters params = cipher.getParameters();
byte[] iv2 = params.getParameterSpec(IvParameterSpec.class).getIV();
ivParams = new IvParameterSpec(iv2);
Run Code Online (Sandbox Code Playgroud) 据我所知,CTR模式不使用初始向量.它只需要一个计数器,用给定的密钥对其进行加密,然后用明文对结果进行异或,以获得密文.
其他分组密码模式,如CBC,在进行加密之前,它们使用初始向量对明文进行异或.
所以这是我的问题.我在Java中使用以下代码(使用bouncycastle库):
Cipher cipher = Cipher.getInstance("AES/CTR/PKCS5Padding", "BC");
cipher.init(Cipher.ENCRYPT_MODE, key);
byte[] result = cipher.doFinal("Some plaintext");
Run Code Online (Sandbox Code Playgroud)
使用相同的键对上述代码的每次不同调用都会产生不同的输出!但是在做的时候:
byte[] IV = new byte[]{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
Cipher cipher = Cipher.getInstance("AES/CTR/PKCS5Padding", "BC");
cipher.init(Cipher.ENCRYPT_MODE, key, IV);
byte[] result = cipher.doFinal("Some plaintext");
Run Code Online (Sandbox Code Playgroud)
我在上述代码的每次调用中都会得到相同的结果.但为什么会这样呢?我的意思是,CTR不需要IV,那么为什么当我不在每次通话中给出IV时我会得到不同的结果,当我给出IV时它会返回相同的结果?如果我在使用点击率时总是使用上面的IV(全零),那会安全吗?
任何想法都会非常有用.谢谢
我需要生成一些随机数据附加到我的文件进行加密.我该怎么做呢?它是否与生成一串随机字符的想法相同?
就像是:
NSData *randomData = @"what should i put here?";
Run Code Online (Sandbox Code Playgroud)
然后使用rand()函数随机化数据?
非常感谢您的帮助
cryptography ×5
encryption ×5
aes ×2
java ×2
pycrypto ×2
python ×2
block-cipher ×1
byte ×1
c# ×1
cocoa ×1
padding ×1
php-openssl ×1
python-3.x ×1
random ×1
secret-key ×1
security ×1