当前位置: 首页 > 面试题库 >

基于Java 256位AES密码的加密

慕弘伟
2023-03-14
问题内容

我需要实现256位AES加密,但是我在网上找到的所有示例都使用“ KeyGenerator”来生成256位密钥,但是我想使用自己的密码。如何创建自己的密钥?我尝试将其填充到256位,但是随后出现错误消息,提示密钥太长。我确实安装了无限管辖权补丁,所以那不是问题:)

就是 KeyGenerator看起来像这样…

// Get the KeyGenerator
KeyGenerator kgen = KeyGenerator.getInstance("AES");
kgen.init(128); // 192 and 256 bits may not be available

// Generate the secret key specs.
SecretKey skey = kgen.generateKey();
byte[] raw = skey.getEncoded();

从这里获取的代码

编辑

我实际上是将密码填充到256个字节而不是位,这太长了。以下是我现在正在使用的一些代码,因为我对此有更多的经验。

byte[] key = null; // TODO
byte[] input = null; // TODO
byte[] output = null;
SecretKeySpec keySpec = null;
keySpec = new SecretKeySpec(key, "AES");
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS7Padding");
cipher.init(Cipher.ENCRYPT_MODE, keySpec);
output = cipher.doFinal(input)

你需要自己做的“ TODO”位:-)


问题答案:

与带外接收者共享password(a char[])saltabyte[]选择的-8个字节,这SecureRandom是个好习惯,不需要保密)。然后从此信息中得出一个好的密钥:

/* Derive the key, given password and salt. */
SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA256");
KeySpec spec = new PBEKeySpec(password, salt, 65536, 256);
SecretKey tmp = factory.generateSecret(spec);
SecretKey secret = new SecretKeySpec(tmp.getEncoded(), "AES");

幻数(可以在某处定义为常数)65536和256分别是密钥派生迭代计数和密钥大小。

迭代密钥派生功能需要大量的计算工作,并且可以防止攻击者快速尝试许多不同的密码。可以根据可用的计算资源来更改迭代次数。

密钥大小可以减小到128位,这仍然被认为是“强”加密,但是如果发现攻击削弱了AES,它的安全边际就不会太大。

与适当的块链接模式一起使用时,相同的派生密钥可用于加密许多消息。在密码块链接(CBC)中,为每个消息生成一个随机初始化向量(IV),即使明文相同,也会产生不同的密文。CBC可能不是你可用的最安全的模式(请参阅下面的AEAD);还有许多其他模式具有不同的安全性属性,但是它们都使用类似的随机输入。无论如何,每个加密操作的输出都是密文和初始化向量:

/* Encrypt the message. */
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
cipher.init(Cipher.ENCRYPT_MODE, secret);
AlgorithmParameters params = cipher.getParameters();
byte[] iv = params.getParameterSpec(IvParameterSpec.class).getIV();
byte[] ciphertext = cipher.doFinal("Hello, World!".getBytes("UTF-8"));

存储ciphertextiv。解密时,SecretKey使用具有相同盐和迭代参数的密码以完全相同的方式重新生成。使用此密钥初始化密码,并使用消息存储初始化向量:

/* Decrypt the message, given derived key and initialization vector. */
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
cipher.init(Cipher.DECRYPT_MODE, secret, new IvParameterSpec(iv));
String plaintext = new String(cipher.doFinal(ciphertext), "UTF-8");
System.out.println(plaintext);

Java 7包括对AEAD密码模式的 API 支持,OpenJDK和Oracle发行版中包括的“ SunJCE”提供程序从Java 8开始实现这些功能。强烈建议使用其中一种模式来代替CBC。它将保护数据的完整性及其隐私。

java.security.InvalidKeyException与消息“非法密钥大小或默认参数”指的是加密强度是有限的; 无限强度管辖权策略文件不在正确的位置。在JDK中,应将它们放置在${jdk}/jre/lib/security

根据问题描述,听起来策略文件未正确安装。系统可以轻松拥有多个Java运行时。仔细检查以确保使用了正确的位置。



 类似资料:
  • 问题内容: 如何基于Java 256位AES密码的加密? 问题答案: 与带外接收者共享和salt 所选择的 - 8个字节,这是个好习惯,不需要保密)。然后从此信息中得出一个好的密钥: 幻数(可以在某处定义为常数)65536和256分别是密钥派生迭代计数和密钥大小。 迭代密钥派生功能需要大量的计算工作,并且可以防止攻击者快速尝试许多不同的密码。可以根据可用的计算资源来更改迭代次数。 密钥大小可以减少

  • 问题内容: 我找到了用Java实施AES加密/解密的指南,并试图理解每一行并将其放入自己的解决方案中。但是,我没有完全理解它,因此出现了问题。最终目标是拥有基于密码的加密/解密。我已经阅读了有关此的其他文章/ stackoverflow帖子,但是大多数文章没有提供足够的解释(我对Java加密非常陌生) 我现在的主要问题是,即使设置了 I,最后还是会得到不同的Base64结果(每次都是随机的,但是我

  • 这是我的密码 抱歉,如果我的代码一团糟。

  • 我需要一些帮助来验证下面的代码片段的Java AES加密与CBC、PKCS5Padding和IV。 我测试了代码,能够加密和解密。我有几个问题如下所述。 密码应该存储在哪里? 向密码文本附加/检索salt和IV字节的方式是否正确? 高度赞赏任何其他评论,谢谢!

  • null 我正在尝试使用Jasypt的StandardPBEStringEncryptor类 当我这样做时,我会得到以下异常: java.security.NosuchAlgorithmException:AES/CBC/PKCS5Padding SecretKeyFactory不可用 谢谢

  • 本文向大家介绍Python3.7 基于 pycryptodome 的AES加密解密、RSA加密解密、加签验签,包括了Python3.7 基于 pycryptodome 的AES加密解密、RSA加密解密、加签验签的使用技巧和注意事项,需要的朋友参考一下 Python3.7 基于 pycryptodome 的AES加密解密、RSA加密解密、加签验签,具体代码如下所示: ps:Python3 RSA加密