我试图用现有代码中的PBEWithMD5AndTripleDES替换PBEWithMD5AndDES.到目前为止,我使用的是之前使用的相同密码,并收到此异常:
java.security.InvalidKeyException:非法的密钥大小
我在网上查看,看到DES使用64位密钥,而TripleDES使用128位密钥.我不清楚我的密码短语如何用于生成密钥的细节,并且不确定在哪里完全理解这一点.我的密码长度为260个字符.我尝试加倍长度,但我得到了同样的例外.
我从我的密码生成一个PBEKeySpec,有一个8字节的盐和12的迭代计数.我看到有另一个构造函数接受一个keyLength参数,但文档将其描述为"要派生",而我不是明白.我有一个想法,我需要修改迭代计数和/或提供一个keyLength参数,但我不想盲目地这样做而不完全理解我在做什么.
以下是我目前使用的代码的基本概要:
String passphrase = ...
byte[] salt = ...
int iterationCount = 12;
String algorithm = "PBEWithMD5AndTripleDES";
KeySpec keySpec = new PBEKeySpec(passPhrase.toCharArray(), salt, iterationCount);
SecretKey key = SecretKeyFactory.getInstance(algorithm).generateSecret(keySpec);
Cipher cipher = Cipher.getInstance(key.getAlgorithm());
AlgorithmParameterSpec paramSpec = new PBEParameterSpec(salt, iterationCount);
cipher.init(Cipher.ENCRYPT_MODE, key, paramSpec);
byte[] encoded = cipher.doFinal(data);
Run Code Online (Sandbox Code Playgroud) 我想允许Alice创建公钥/私钥对,以便Bob可以发送她的机密消息.但是,我希望Alice能够从任何地方检查她的消息,并且她必须携带包含她的私钥的记忆棒是一件痛苦的事.Alice是否有某种方法可以根据她记得的密码创建公钥/私钥对?通过这种方式,她可以随时生成私钥(和公钥).
这个问题的简短版本是:我在哪里可以找到cryptico.js的Java等价物.
另外,这是关于Stack Overflow 的相同问题,但是对于javascript.
编辑:这是我第一次尝试解决方案:
SecureRandom saltRand = new SecureRandom(new byte[] { 1, 2, 3, 4 });
byte[] salt = new byte[16];
saltRand.nextBytes(salt);
int keyLength = 3248;
SecretKeyFactory factory = SecretKeyFactory
.getInstance("PBKDF2WithHmacSHA1");
KeySpec spec = new PBEKeySpec(password.toCharArray(), salt, 8192, keyLength);
SecretKey key = factory.generateSecret(spec);
SecureRandom keyGenRand = SecureRandom.getInstance("SHA1PRNG");
keyGenRand.setSeed(key.getEncoded());
KeyPairGenerator gen = KeyPairGenerator.getInstance("RSA");
gen.initialize(keyLength, keyGenRand);
java.security.KeyPair p = gen.generateKeyPair();
Run Code Online (Sandbox Code Playgroud) 我正在做一些Java加密,并且无法找到正确使用PBEWithHmacSHA512AndAES_256算法的方法.
加密似乎工作正常,但我无法正确初始化解密密码.
以下是一个演示该问题的简短程序.特别是,请参阅"问题"评论.
注意:我已经看到了这个非常有用的答案,我可以使用该方案让事情发挥作用,但我很想知道我在这里做错了什么.
import java.nio.charset.StandardCharsets;
import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.PBEKeySpec;
import javax.crypto.spec.PBEParameterSpec;
public final class CryptQuestion {
private static final String ALGORITHM = "PBEWithHmacSHA512AndAES_256";
private static final int ITERATIONS = 1000; // Aside: not sure what is a good number, here.
public static void main(final String[] args) throws Exception {
final String message = "This is the secret message... BOO!";
System.out.println("Original : " + message);
final byte[] messageBytes = message.getBytes(StandardCharsets.US_ASCII);
final String …Run Code Online (Sandbox Code Playgroud) 我用低于此值的文件(10mb,100mb,500mb)测试了我的代码,加密工作正常.但是,我遇到了大于1GB的文件的问题.我已经生成了一个大文件(大约2GB),我想用AES使用JAVA加密它,但我遇到了这个错误:
"线程中的异常"主"java.lang.OutOfMemoryError:Java堆空间"
我尝试使用-Xmx8G增加可用内存,但没有骰子.我的部分代码如下
File selectedFile = new File("Z:\\dummy.txt");
Path path = Paths.get(selectedFile.getAbsolutePath());
byte[] toencrypt = Files.readAllBytes(path);
byte[] ciphertext = aesCipherForEncryption.doFinal(toencrypt);
FileOutputStream fos = new FileOutputStream(selectedFile.getAbsolutePath());
fos.write(ciphertext);
fos.close();
Run Code Online (Sandbox Code Playgroud)
据我所知,它的行为方式是,它试图立即读取整个文件,加密它,并将其存储到另一个字节数组中,而不是缓冲和流式传输.任何人都可以帮助我一些代码提示?
我是编码的初学者,所以我真的不太了解,任何帮助都将受到赞赏.
我正在制作一个简单的程序,它在文本框中输入文本,并获取另一个文本框中的密码,然后对其进行某种简单加密并将其保存到文件中.之后,用户应该能够再次打开文件并提供用于加密的密码,并且应该吐出原始文本.
现在我正在拿绳子.将其分隔为char数组,然后对密码执行相同操作.之后,我获取密码,将所有这些字符转换为整数,找到所有字符的平均值,并将其用作原始文本中字符的偏移量.有一些像:
textChars[1]= (char)((int)textChars[1]+offset);
Run Code Online (Sandbox Code Playgroud)
然后我可以反过来加密字符串:
encryptedChars[1]= (char)((int)encryptedChars[1]-offset);
Run Code Online (Sandbox Code Playgroud)
问题是字符在不同平台上具有不同的值,因此有时偏移会将字符变成一些疯狂的数字(如负值),这只会将字符变成问号.
我查看了标准Java API中的加密库,但是如果每次启动程序时随机生成密钥,我会感到困惑.
我需要的是两个函数,它们看起来像是String encrypt(String text,String Password)用密码加密的文本作为解密它的密钥,并且String decrypt(String encryptedText, String Password)会吐出原始文本(如果密码是垃圾则会乱码)
任何帮助都非常感谢,这实际上只是一个个人项目,所以我不需要任何花哨的加密方法.
我正在用Java编写安全的文件共享应用程序.一般架构如下所示:
这是捕获.用户的私钥必须加密并存储在我们数据库的服务器上,以便可以从多个位置访问这些文件.在上传到服务器之前,私钥将在客户端上使用用户选择的密码进行加密.
我想使用AES 256位加密来做到这一点.而且我想在不依赖BouncyCastle库或任何第三方库的情况下完成整个过程.它需要使用标准的Java 5库,这就是我选择使用AES 256加密和RSA而不是像PGP这样的原因.
任何人都可以找到任何本质上不安全的方法,或者想一个更有效的方法来做到这一点?
编辑:
好的,我正在更新问题,因为我得到的所有答案都表明我没有将私钥传输到服务器.我需要服务器上的私钥的原因是因为用户需要能够从多个客户端和多个位置(即:他们的iphone,他们的ipad,他们的工作笔记本电脑,他们的家用电脑)访问他们的数据.他们不希望必须在设备之间管理和复制他们的密钥,这比将密钥存储在我们的服务器上更加不安全,因为他们最终会在那时通过电子邮件将它们发送给自己.
从如何实现基于密码的加密来看,很明显我需要保存盐、IV 和密文以便稍后解密。
我以这种格式存储十六进制值
DatatypeConverter.printHexBinary(salt) + DatatypeConverter.printHexBinary(iv) + DatatypeConverter.printHexBinary(ciphertext);
我需要以二进制格式存储值吗?
DatatypeConverter.printBase64Binary(salt) + DatatypeConverter.printBase64Binary(iv) + DatatypeConverter.printBase64Binary(ciphertext));
输出清楚地表明盐、静脉注射结束的位置,这太糟糕了
lIvyAA/PZg4=fE4gTZUCPTrKQpUKo+Z1SA==4/gAdiOqyPOAzXR69i0wlC7YFn9/KOGitZqpOW2y3ms=
Run Code Online (Sandbox Code Playgroud)
以十六进制格式存储是否会导致数据丢失?
IV 的长度是恒定的吗?就我而言,它始终是 32 个字符(十六进制),或者我什至还需要存储 IV 的长度?因为盐长度最初固定为 8 位(16 个十六进制字符)
(我使用 PBKDF2WithHmacSHA1 算法进行密钥生成,使用 AES/CBC/PKCS5Padding 进行密码)
我在C#中有以下代码.它使用AES对称算法对字节数组进行编码.我需要编写相当于此代码的Java.
class Program
{
static void Main(string[] args)
{
string a = "ABCDEFGHIJKLMNOP";
byte[] bytes = Encoding.ASCII.GetBytes(a);
byte[] cipher = encode(bytes, "1111111122222222111111112222222211111111222222221111111122222222", "66666666555555556666666655555555");
}
private static byte[] encode(byte[] toEncrypt, string sKey, string sIV)
{
byte[] IV = new byte[16];
byte[] key = new byte[32];
byte[] array = new byte[toEncrypt.Length];
string s;
for (int i = 0; i < IV.Length; ++i)
{
s = sIV.Substring(i * 2, 2);
IV[i] = Convert.ToByte(s, 16);
}
for (int i = 0; i < key.Length; …Run Code Online (Sandbox Code Playgroud) 有什么方法可以得到与 MySQL 中相同的结果
SELECT AES_ENCRYPT("text", "key")
Run Code Online (Sandbox Code Playgroud)
使用Java函数?
如果可能的话,模拟 AES_DECRYPT 的另一个函数是什么?
我想尝试加密文件并使用以下堆栈溢出响应。然而,在测试初始化向量时,我发现它只影响前 16 个字节。
当我将一个空的 iv 传递给解密密码(前 16 个字节除外)时,数据被意外解密。 [我假设图书馆没有坏,而且我做的事情不正确;但这是一个可怕的想法,其他人可能在同一条船上却没有意识到这一点。]
例子:
Initial bytes ..... 2222222222222222222222222222222222222222222222222222
Encrypted bytes ... b35b3945cdcd08e2f8a65b353ff754c32a48d9624e16b616d432
Decrypted bytes ... 3c4154f7f33a2edbded5e5af5d3d39b422222222222222222222
Run Code Online (Sandbox Code Playgroud)
问:为什么整个解密没有失败?
推测:我想我可以通过一次迭代 16 个字节的数据并通过对先前加密的 16 个字节块进行散列来更新每轮的 iv 来进行加密。然而,这似乎是我期望图书馆做的繁忙的工作。我本来希望提出实施指南的专家会提到它。但我只是抓住了这里的稻草。据我所知,也许安全社区只担心第一个区块的黑客攻击。
注意:刚才我发现了一个 5.5 年前的堆栈溢出帖子,它发现了同样的问题;不幸的是,它仍然没有回应。
package test;
import java.security.AlgorithmParameters;
import java.security.spec.KeySpec;
import java.util.Formatter;
import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.PBEKeySpec;
import javax.crypto.spec.SecretKeySpec;
/*
* Issue: Using "AES/CBC/PKCS5Padding" encryption, the Initialization Vector
* appears to only affect the first block?!?
*
* Example Output
* iv …Run Code Online (Sandbox Code Playgroud) java ×10
encryption ×9
aes ×4
cryptography ×3
byte ×1
encoding ×1
hex ×1
mysql ×1
netbeans-8 ×1
private-key ×1
rsa ×1
string ×1