security - 带有充气城堡的 scala 中的 AES-256 加密工作流程 : salt and IV usage and transfer/storage

标签 security encryption aes bouncycastle password-encryption

我正在尝试对通过不安全通道发送或存储在不安全位置的文件实现安全加密。我用bouncy castle框架,我的代码写在 。我决定使用 -256(更具体地说 - Rinjael 具有 256 位 block 大小, here is why )。看起来我可以将 Rinjael 与任何 (128|160|192|256) block 长度一起使用。

我无法正确理解整个过程的概述。 Here是很好的答案之一,in this question有一些特定于充气城堡的有用代码。但两者都给我留下了一些未解答的问题(问题如下)。

这就是我对工作流程的理解:

  1. 为了创建分组密码实例,我必须获取带有一些输出反馈的填充分组密码实例:

    // create an instance of the engine
    val engine = new RijndaelEngine(bitLength)
    // wrap engine with some feedback-blocking cipher mode engine
    val ofb = new OFBBlockCipher(engine , bitLength)
    // wrap this with some padded-blocking cipher mode
    val cipher = new PaddedBufferedBlockCipher(ofb, new PKCS7Padding())
    
  2. 现在我必须在密码引擎上运行 init()

    2.1。首先生成一个 key ,为此建议最好的解决方案here是使用 Scrypt 从密码中获取 secret ,而不是使用 PBKDF2-HMAC-xxx。在 russian wikipedia article on Scrypt据说Scrypt的推荐参数如下:N = 16384, r = 8, p = 1 所以我编写了这段代码来生成密码:

    SCrypt.generate(password.getBytes(encoding), salt, 16384, 8, 1, bitLength / 8)
    

    2.2。这导致我需要盐。盐should be an array of random bytes 。最answers在这里use 8 字节。所以我愿意

    // helper method to get a bunch of random bytes
    def getRandomBytes(size: Int) = {
      val bytes = Array.ofDim[Byte](size)
      val rnd = new SecureRandom()
      rnd.nextBytes(bytes)
      bytes
    }
    // generate salt
    val salt = getRandomBytes(8)
    

    2.3。为了初始化密码,我们需要一个初始化向量(请看下面我的问题(2))。

    val iv = getRandomBytes(bitLength / 8)
    

    2.4。现在我们准备初始化密码。

    cipher.init(mode, params(password, salt, iv, bitLength))
    

问题:

  1. 盐的大小应该是多少?为什么大多数respondents在这里use 8 字节,而不是更多?
  2. IV 的大小应该是多少?它的大小应该与密码 block 大小相同,这是否正确?是否首选从密码中获取 like here : cipher.getParameters().getParameterSpec(IvParameterSpec.class).getIV(); 还是像我一样随机?
  3. 我需要两者盐和静脉注入(inject),或者我可以只使用其中之一,这是正确的吗?例如使用随机 IV 作为盐。
  4. 主要问题:我必须将盐和 IV 传递给另一方,否则将无法解密消息。我需要以某种方式将两者通过未加密的 channel 传递。在加密消息之前添加两者(作为 header )是否安全

提前致谢!

最佳答案

  1. 我会选择 16 字节的盐长度,如 suggested
  2. IV 应该是密码 block 大小的大小,并且应该是随机的
  3. 是的,您需要 salt 和 IV,因为 salt 用于从密码生成 key ,IV 用于初始化分组密码
  4. Salt 和 IV 旨在公开。您可以以未加密的方式发送或存储它们,但您不使用任何身份验证机制,因此任何人都可以在传输过程中更改 IV 或 Salt,而您将无法检测到它,解密会给您带来不同的结果。为了防止这种情况,您应该使用一些 AEAD模式并在身份验证中包含 IV 和盐。

关于security - 带有充气城堡的 scala 中的 AES-256 加密工作流程 : salt and IV usage and transfer/storage,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19301244/

相关文章:

c - 使用对称 key 加密数组

encryption - Jenkins 解密 API token

java - AES 256 位加密 - java.security.InvalidAlgorithmParameterException : Wrong IV length: must be 16 bytes long

sql-server - 如何从域管理员那里保护 SQL 数据库?

security - session 管理 : How to generate Authentication token for REST service ?( Jersey )

security - 如何在分布式系统中管理用户(资源访问、身份验证)?

security - 在 RSS 提要 URL 中嵌入用户名/密码时是否存在任何安全隐患?

php - 在nodejs中使用初始向量进行aes-256-cbc加密解密

android - 使用 AES (MODE_CBC/NoPadding) 解密 iOS 中用 Python 加密的文件

c# - 从加密流读取到流的末尾