美好的一天,我需要使用base64编码加密一些文本,并将编码数据传递给.NET应用程序。 .NET应用程序使用以下形式的编码和解码。我试过这个Equivalent to CryptoStream .NET in Java?。 为了这个目的,我在上面的链接之后使用了Apache commons编解码器。但坚持使用cryptoProvider.CreateEncryptor(bytes,bytes),当我检查java等价物中的第三个参数时 -
Cipher.init(cipher.ENCRYPT_MODE,键,ⅳ)
它必须是IvParameterSpec。我不知道如何解决这个问题。希望得到一些帮助,干杯!
.NET加密
static byte[] bytes = ASCIIEncoding.ASCII.GetBytes("mykey");
public static string Encrypt(string originalString)
{
DESCryptoServiceProvider cryptoProvider = new DESCryptoServiceProvider();
MemoryStream memoryStream = new MemoryStream();
CryptoStream cryptoStream = new CryptoStream(memoryStream,cryptoProvider.CreateEncryptor(bytes, bytes), CryptoStreamMode.Write);
StreamWriter writer = new StreamWriter(cryptoStream);
writer.Write(originalString);
writer.Flush();
cryptoStream.FlushFinalBlock();
writer.Flush();
return Convert.ToBase64String(memoryStream.GetBuffer(), 0, (int)memoryStream.Length);
}
等价
Java加密
void encrypt(String inputText) throws Exception {
try {
String myKey = "mykey";
byte[] mybyte = str.getBytes("ASCII");
//String plainIV = "1234567890ABCDEF";
KeySpec keySpec = new DESKeySpec(myKey.getBytes("ASCII"));
SecretKey key = SecretKeyFactory.getInstance("DES").generateSecret(keySpec);
//IvParameterSpec iv = new IvParameterSpec(org.apache.commons.codec.binary.Hex.decodeHex(plainIV.toCharArray()));
IvParameterSpec iv = new IvParameterSpec(mybyte);
Cipher cipher = Cipher.getInstance("DES/CBC/PKCS5Padding");
cipher.init(Cipher.ENCRYPT_MODE,key,iv);
byte[] encoded = cipher.doFinal(inputText.getBytes("ASCII"));
System.out.println("Encoded Value ..... "+Base64.encodeBase64(encoded));
} catch(UnsupportedEncodingException e) {
System.out.println("Exception .. "+ e.getMessage());
}
在.Net中我得到了这个 - AOb0B20x2onFGz + JaFBsZyFbvCS9WF49D作为编码值,但是在java中,我得到有线编码的字符串 - = SKNv? N Ɛq{ U ; /Z 8 LT;
编辑: -
跟随zacheusz并解决了编码问题,但.NET和java中的编码字符串都不同......
答案 0 :(得分:2)
我在.NET中看到你正在进行IV:
cryptoProvider.CreateEncryptor(bytes, bytes)
根据documentation,第二个字节数组是IV。所以你应该在Java中使用相同的数组。
我认为错误就在这里:
cipher.doFinal(Base64.encodeBase64(inputText.getBytes("ASCII")));
在解密之前你是b64编码输入。
尝试
byte[] output = cipher.doFinal(inputText.getBytes("ASCII"));
System.out.println("Encoded Value ..... "+new String(Base64.encodeBase64(output)));
补充说明(关于您在评论中提出的问题):
答案 1 :(得分:1)
谢谢@zacheusz, 我知道了!!! 这是一个愚蠢的错误,我正在打印byte []值,我忘记将其转换为String
如此改变
System.out.println(“编码值.....”+ Base64.encodeBase64(编码));
要
System.out.println(“编码值.....”+新字符串(Base64.encodeBase64(编码),“ASCII”);
并解决了我的问题。还使用ByteArrayOutputStream修改了代码。 这是编码&解码功能
String encrypt(String inputText) throws Exception {
byte[] keyValue = new byte[] { 'm', 'y', 'k', 'e', 'y', 'n', 'u', 'l'};
ByteArrayOutputStream bout = new ByteArrayOutputStream();
try {
KeySpec keySpec = new DESKeySpec(keyValue);
SecretKey key = SecretKeyFactory.getInstance("DES").generateSecret(keySpec);
IvParameterSpec iv = new IvParameterSpec(keyValue);
Cipher cipher = Cipher.getInstance("DES/CBC/PKCS5Padding");
cipher.init(Cipher.ENCRYPT_MODE,key,iv);
bout.write(cipher.doFinal(inputText.getBytes("ASCII")));
} catch(Exception e) {
System.out.println("Exception .. "+ e.getMessage());
}
return new String(Base64.encodeBase64(bout.toByteArray()),"ASCII");
}
String decrypt(String inputText) throws Exception {
byte[] keyValue = new byte[] { 'm', 'y', 'k', 'e', 'y', 'n', 'u', 'l'};
try {
KeySpec keySpec = new DESKeySpec(keyValue);
SecretKey key = SecretKeyFactory.getInstance("DES").generateSecret(keySpec);
IvParameterSpec iv = new IvParameterSpec(keyValue);
Cipher cipher = Cipher.getInstance("DES/CBC/PKCS5Padding");
cipher.init(Cipher.DECRYPT_MODE,key,iv);
//byte[] decoded = Base64.decodeBase64(inputText); //Works with apache.commons.codec-1.8
byte[] decoded = Base64.decodeBase64(inputText.getBytes("ASCII"));// works with apache.commons.codec-1.3
bout.write(cipher.doFinal(decoded));
} catch(Exception e) {
System.out.println("Exception ... "+e);
}
return new String(bout.toByteArray(),"ASCII");
}
希望有人会发现它有用......