我正在尝试通过网络发送受保护的文本,使用AES算法和Base64对其进行加密。对于我试过的几个文本,它工作正常,但有一些字符串没有正确解码。 我在字符串上发现了一个无法解码的模式。它们似乎是它们的突破线。 例: 加密步骤:
1)PlainText
2)AES加密文本:
即 l1?‰|6ÎÔ.jcæ÷Ï_ðNSO〜A'q @Ó[
3)BASE64 AES文本:
zWUNbDEgnz + JfDbO1C5qY + b3z1 / wTlNPmAdBknFA01s =
解密步骤:
1)BASE64 AES文本:
zWUNbDEgnz + JfDbO1C5qY + b3z1 / wTlNPmAdBknFA01s =
2)AES加密文本:
即 l1?‰|6ÎÔ.jcæ÷Ï_ðNSO〜A'q @Ó[
3)纯文本:
í¿Ð“tº“£¹ÍG‰\ IOE
我加密的任何其他文本都不包含加密版本的分隔线,这是正确解密的。
例如:
加密步骤:
1)纯文本:P @ $$ w0rd
2)AES加密文本:
÷÷Odã29ôÐÑÌe£ø™
3)Base64 AES文本:
9xH3T2TjMjn00NHMZaOZ + A ==
解密步骤:
3)Base64 AES文本:
9xH3T2TjMjn00NHMZaOZ + A ==
2)AES加密文本:
÷÷Odã29ôÐÑÌe£ø™
3)纯文本:
2P @ $$ w0rd
以下是我为此目的创建的对象。
Base64Codec对象:
package security;
import java.util.Base64;
import java.util.Base64.Decoder;
import java.util.Base64.Encoder;
public class Base64Codec
{
private static Base64Codec objInstance;
private Encoder objEncoder;
private Decoder objDecoder;
private Base64Codec()
{
this.setEncoder();
this.setDecoder();
}
public static Base64Codec getInstance()
{
if (objInstance == null)
{
objInstance = new Base64Codec();
}
return objInstance;
}
private void setEncoder()
{
this.objEncoder = Base64.getEncoder();
}
private Encoder getEncoder()
{
return this.objEncoder;
}
private void setDecoder()
{
this.objDecoder = Base64.getDecoder();
}
private Decoder getDecoder()
{
return this.objDecoder;
}
protected String encode(String strValue)
{
return this.getEncoder().encodeToString(strValue.getBytes());
}
protected String decode(String strValue)
{
return new String(this.getDecoder().decode(strValue));
}
}
AdvancedEncryptionStandard Object
package security;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.spec.SecretKeySpec;
public class AdvancedEncryptionStandard
{
private static final String strKey = "02E68E02BE7400FE11E8A45B60017F98";
private static final byte[] bytKey = strKey.getBytes();
private static final String strAlgorithm = "AES";
private static AdvancedEncryptionStandard objInstance;
private Cipher objCipher;
private SecretKeySpec objSecretKey;
private AdvancedEncryptionStandard() throws NoSuchAlgorithmException, NoSuchPaddingException
{
this.setSecretKey();
this.setCipher();
}
public static AdvancedEncryptionStandard getInstance() throws NoSuchAlgorithmException, NoSuchPaddingException
{
if (objInstance == null)
{
objInstance = new AdvancedEncryptionStandard();
}
return objInstance;
}
private byte[] getKey()
{
return bytKey;
}
private String getAlgorithm()
{
return strAlgorithm;
}
private void setSecretKey()
{
this.objSecretKey = new SecretKeySpec(this.getKey(), this.getAlgorithm());
}
private SecretKeySpec getSecretKey()
{
return this.objSecretKey;
}
private void setCipher() throws NoSuchAlgorithmException, NoSuchPaddingException
{
this.objCipher = Cipher.getInstance(this.getAlgorithm());
}
private Cipher getCipher()
{
return this.objCipher;
}
protected String encrypt(String strValue) throws InvalidKeyException, IllegalBlockSizeException, BadPaddingException
{
this.getCipher().init(Cipher.ENCRYPT_MODE, this.getSecretKey());
return new String(this.getCipher().doFinal(strValue.getBytes()));
}
protected String decrypt(String strValue) throws InvalidKeyException, IllegalBlockSizeException, BadPaddingException
{
this.getCipher().init(Cipher.DECRYPT_MODE, this.getSecretKey());
return new String(this.getCipher().doFinal(strValue.getBytes()));
}
}
SecureText对象
package security;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import javax.crypto.BadPaddingException;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
public class SecureText
{
private static SecureText objInstance;
private SecureText()
{
}
public static SecureText getInstance()
{
if (objInstance == null)
{
objInstance = new SecureText();
}
return objInstance;
}
public String encode(String strValue) throws InvalidKeyException, IllegalBlockSizeException, BadPaddingException, NoSuchAlgorithmException, NoSuchPaddingException
{
return Base64Codec.getInstance().encode(AdvancedEncryptionStandard.getInstance().encrypt(strValue));
}
public String decode(String strValue) throws InvalidKeyException, IllegalBlockSizeException, BadPaddingException, NoSuchAlgorithmException, NoSuchPaddingException
{
return AdvancedEncryptionStandard.getInstance().decrypt(Base64Codec.getInstance().decode(strValue));
}
}
测试:
public static void main(String[] args)
{
//Test SecureText Object. AES and Base64
String strSecureText = <plain text>
System.out.println(strSecureText);
System.out.println(SecureText.getInstance().decode(strSecureText));
//Test AES and Base64 separated
String strCoded;
String strEncrypted;
String strDecrypted;
String strDecoded;
strEncrypted = AdvancedEncryptionStandard.getInstance().encrypt(<plain text>);
System.out.println(strEncrypted);
strCoded = Base64Codec.getInstance().encode(strEncrypted);
System.out.println(strCoded);
strDecoded = Base64Codec.getInstance().decode(strCoded);
System.out.println(strDecoded);
strDecrypted = AdvancedEncryptionStandard.getInstance().decrypt(strDecoded);
System.out.println(strDecrypted);
String strSecureText = SecureText.getInstance().encode(<plain text>);
}
答案 0 :(得分:1)
我看到你的代码有两个问题(关于加密,对于你已经有足够评论的结构)
对于我尝试过的几个文本,它工作正常,但有一些字符串未正确解码。我在字符串上发现了一个无法解码的模式。
永远不要尝试将Java中的随机字节数组表示为String
。 JVM将尝试暗示字符集转换,您可能会丢失/更改数据。将String
转换为字节时同样适用,最好明确说明编码。
加密数据只是一个字节数组,一旦计划打印它们,就将字节数组编码为可读的内容,例如hex或base64。请勿使用new String(encryptedArray)
下一个问题是我没有看到你使用IV(而且似乎要求进行身份验证加密),请阅读我的blog about how to do encryption at least almost properly。