我有自己的方法。net项目来加密密码
public string Encrypt(string plainText)
{
string PassPhrase = "#$^&*!@!$";
string SaltValue = "R@j@}{BAe";
int PasswordIterations = Convert.ToInt32(textBox5.Text); //amend to match java encryption iteration
string InitVector = "@1B2c3D4e5F6g7H8";
int KeySize = 256; //amend to match java encryption key size
byte[] initVectorBytes = Encoding.ASCII.GetBytes(InitVector);
byte[] saltValueBytes = Encoding.ASCII.GetBytes(SaltValue);
byte[] plainTextBytes = Encoding.UTF8.GetBytes(plainText);
PasswordDeriveBytes password= new PasswordDeriveBytes(
PassPhrase,
saltValueBytes,
"MD5",
PasswordIterations);
byte[] keyBytes = password.GetBytes(KeySize / 8);
RijndaelManaged symmetricKey = new RijndaelManaged();
symmetricKey.Mode = CipherMode.CBC;
ICryptoTransform encryptor = symmetricKey.CreateEncryptor(
keyBytes,
initVectorBytes);
MemoryStream memoryStream = new MemoryStream();
CryptoStream cryptoStream = new CryptoStream(memoryStream,
encryptor,
CryptoStreamMode.Write);
cryptoStream.Write(plainTextBytes, 0, plainTextBytes.Length);
cryptoStream.FlushFinalBlock();
byte[] cipherTextBytes = memoryStream.ToArray();
memoryStream.Close();
cryptoStream.Close();
string cipherText = Convert.ToBase64String(cipherTextBytes);
return cipherText;
}
我的任务是将此方法转换为java,但在java中,我没有得到与该方法相同的结果。网络版
我的java代码是
package com.andc.billing.pdc.security;
import java.io.UnsupportedEncodingException;
import java.security.InvalidAlgorithmParameterException;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.InvalidParameterSpecException;
import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.PBEKeySpec;
import javax.crypto.spec.SecretKeySpec;
import javax.management.openmbean.InvalidKeyException;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
public class PasswordCrypto {
private static final String password = "#$^&*!@!$";
private static String initializationVector = "@1B2c3D4e5F6g7H8";
private static String salt = "R@j@}{BAe";
private static int pswdIterations = 2;
private static int keySize = 128;
private static final Log log = LogFactory.getLog(PasswordCrypto.class);
public static String encrypt(String plainText) throws
NoSuchAlgorithmException,
InvalidKeySpecException,
NoSuchPaddingException,
InvalidParameterSpecException,
IllegalBlockSizeException,
BadPaddingException,
UnsupportedEncodingException,
InvalidKeyException,
InvalidAlgorithmParameterException, java.security.InvalidKeyException, NoSuchProviderException
{
byte[] saltBytes = salt.getBytes("ASCII");//"UTF-8");
byte[] ivBytes = initializationVector.getBytes("ASCII");//"UTF-8");
// Derive the key, given password and salt.
SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1");//PBEWithMD5AndDES");
PBEKeySpec spec = new PBEKeySpec(
password.toCharArray(),
saltBytes,
pswdIterations,
keySize
);
SecretKey secretKey = factory.generateSecret(spec);
SecretKeySpec secret = new SecretKeySpec(secretKey.getEncoded(), "AES");
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); //Cipher.getInstance("AES/CBC/PKCSPadding"
cipher.init(Cipher.ENCRYPT_MODE, secret, new IvParameterSpec(ivBytes));
byte[] encryptedTextBytes = cipher.doFinal(plainText.getBytes("ASCII"));//UTF-8"));
String str=new org.apache.commons.codec.binary.Base64().encodeAsString(encryptedTextBytes);
log.info(str);
return str;
}
}
。net
加密“1”的结果是:
7mPh3/E/olBGbFpoA18oqw==
而java是
7RPk77AIKAhOttNLW4e5yQ==
你能帮我解决这个问题吗?
非常感谢您提供的解决方案-它工作得非常好,但有一点修正(根据下面提到的最初帖子):
请使用:
b = generateExtendedKey(count);
而不是:
b = generateExtendedKey(++count);
即使对于256键大小,它也可以工作:
下面是一个使用256位密钥解密C#Rijndael编码数据的小代码:
public static String decrypt(final String cipherText, final String passPhrase, final String saltValue, final int passwordIterations, final String initVector, final int keySize)
throws Exception {
final byte[] initVectorBytes = initVector.getBytes("ASCII");
final byte[] saltValueBytes = saltValue.getBytes("ASCII");
final byte[] cipherTextBytes = Base64.decode(cipherText);
final PKCS5S1ParametersGenerator generator = new PasswordDeriveBytes(new SHA1Digest());
generator.init(passPhrase.getBytes("ASCII"), saltValueBytes, passwordIterations);
final byte[] key = ((KeyParameter) generator.generateDerivedParameters(keySize)).getKey();
final SecretKey secretKey = new SecretKeySpec(key, ALGORITHM);
final Cipher cipher = Cipher.getInstance(TRANSFORMATION);
final IvParameterSpec iv = new IvParameterSpec(initVectorBytes);
cipher.init(Cipher.DECRYPT_MODE, secretKey, iv);
final byte[] decryptedVal = cipher.doFinal(cipherTextBytes);
return new String(decryptedVal);
}
插件:如果你关心密钥大小限制,你可以使用这个解决方案,它工作得很好(在Ubuntu12下测试,Java 1.7 64位(Java版本“1.7.0_25”Java(TM)SE运行时环境(构建1.7.0_25-b15)Java热点(TM)64位服务器VM(构建23.25-b01,混合模式))
我注意到的第一件事是,你所使用的算法是不同的。Net它是PBKDF1的扩展,在java中它是PBKDF2,PBKDF2取代了PBKDF1。
在里面net您正在使用PasswordDeriveBytes类,该类“使用PBKDF1html" target="_blank">算法的扩展从密码中派生密钥。”
我还注意到,密码迭代是硬编码为2在Java,并来自一个文本框中。网...确保它们是一样的。
纠正这一点,让我们知道结果。
更新:适用于中的PBKDF2。net使用Rfc2898DeriveBytes类。
对于一些非常好的相关信息有阅读本页
编辑:这个链接应该是有帮助的,如果你可以使用Chilkat库
1和2之间有一个复杂的区别,1最多只能处理20个字节,MS已经构建了一个扩展,它允许更多的字节,下面的代码应该会重新生成。净产出更准确。从这里开始。
import org.bouncycastle.crypto.CipherParameters;
import org.bouncycastle.crypto.Digest;
import org.bouncycastle.crypto.digests.SHA1Digest;
import org.bouncycastle.crypto.generators.PKCS5S1ParametersGenerator;
import org.bouncycastle.crypto.params.KeyParameter;
import org.bouncycastle.util.encoders.Hex;
public class PKCS5Test
{
/**
* @param args
*/
public static void main(String[] args) throws Exception
{
byte[] password = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 };
byte[] salt = PKCS5S1ParametersGenerator.PKCS5PasswordToBytes("MyTesting".toCharArray());
PKCS5S1ParametersGenerator generator = new PasswordDeriveBytes(new SHA1Digest());
generator.init(password, salt, 100);
byte[] key = ((KeyParameter)generator.generateDerivedParameters(512)).getKey();
System.out.println( "64 " + new String(Hex.encode(key)).toUpperCase() );
}
static class PasswordDeriveBytes extends PKCS5S1ParametersGenerator
{
private final Digest d;
private byte[] output = null;
public PasswordDeriveBytes(Digest d)
{
super(d);
this.d = d;
}
public CipherParameters generateDerivedParameters(int keySize)
{
keySize = keySize / 8;
byte[] result = new byte[keySize];
int done = 0;
int count = 0;
byte[] b = null;
while (done < result.length)
{
if (b == null)
{
b = generateInitialKey();
}
else if (++count < 1000)
{
b = generateExtendedKey(++count);
}
else
{
throw new RuntimeException("Exceeded limit");
}
int use = Math.min(b.length, result.length - done);
System.arraycopy(b, 0, result, done, use);
done += use;
}
return new KeyParameter(result);
}
private byte[] generateOutput()
{
byte[] digestBytes = new byte[d.getDigestSize()];
d.update(password, 0, password.length);
d.update(salt, 0, salt.length);
d.doFinal(digestBytes, 0);
for (int i = 1; i < (iterationCount - 1); i++)
{
d.update(digestBytes, 0, digestBytes.length);
d.doFinal(digestBytes, 0);
}
return digestBytes;
}
private byte[] generateInitialKey()
{
output = generateOutput();
d.update(output, 0, output.length);
byte[] digestBytes = new byte[d.getDigestSize()];
d.doFinal(digestBytes, 0);
return digestBytes;
}
private byte[] generateExtendedKey(int count)
{
byte[] prefix = Integer.toString(count).getBytes();
d.update(prefix, 0, prefix.length);
d.update(output, 0, output.length);
byte[] digestBytes = new byte[d.getDigestSize()];
d.doFinal(digestBytes, 0);
//System.err.println( "X: " + new String(Hex.encode(digestBytes)).toUpperCase() );
return digestBytes;
}
}
}
我已经尝试使用cipher.getinstance(“rsa/ecb/pkcs1padding”),但没有给出预期的结果。 感谢所有的帮助。祝你有美好的一天。
问题内容: PHP功能: Java函数 } 返回null。 请注意,我们不允许更改PHP代码。有人可以帮助我们在Java中获得相同的结果吗?非常感谢。 问题答案: 如果您不只是简单地将例程中的可能内容吞噬掉,那么您将对发生的事情有了更好的了解。如果函数正在返回,那么显然发生了异常,您需要知道它是什么。 实际上,例外是: 可以肯定的是,您的纯文本长度只有11个Java字符,按照您的默认编码,它将为1
我正在加密字符串“AAAAAAAAAAAAAAAAAAAAAAAA”(一个16字节的UTF8字符串)使用AES 128 CBC与空白iv和密钥(16 0),并得到不同的结果 在PHP中: 第一位(粗体)与PHP相同,但PHP值有一个额外的“a=”,然后节点值有一个额外的“heuidae8z4dk0hu7p2z+1c” 我承认我对这里发生的事情很不确定--我错过了什么? 编辑...但不是那么不稳定,
问题内容: 我正在尝试使用RSA算法在.NET中加密字符串,并在Java中解密结果。目前,我已经可以做相反的事情(用Java加密,用.NET解密)。这里有我的代码可以实际工作(JAVA加密): 和(.NET解密) 现在我想做相反的事情……但是我遇到了一些错误,例如(密钥的大小应该是128个字节……等等)我应该怎么做? 在这里,我添加当前的 无效 代码: 。净 爪哇 问题答案: Java解密代码的最
问题内容: 我正在使用RSA在JAVA上进行加密,并尝试使用.NET进行解密。我包括我的JAVA代码和.NET代码,希望有人对此有所了解。 JAVA代码: 从此JAVA代码中,我得到了加密字符串的结果,该结果恰好是: FOP4 AAIH6hcabXnrvNG5YUk + / + nBv9n9HU0CAgZjkIWQIDjbOpSwoPVBFERrZ6641x2QaoJw5yv18XAay 0WrC
我工作在AES256能够加密/解密之间的iOS和PHP使用不安全的渠道。 我见过许多类似的问题,围绕着密钥大小、模式(CBC或ECB)、随机iv的使用等。但是在这种情况下,我发现了以下奇怪的行为。 两种环境中的配置:-键:32字节(256位)-块大小:128位(标准)-iv:16字节(用于测试的静态)-模式:CBC 如果我加密一个16或32字节的文本(以匹配AES块大小),Swift和PHP中的结