2017-01-16 157 views
1

我必须在我的程序中实施基本加密。我可以使用Base64,它被客户端拒绝。所以我正在使用以下方法。我面临的问题是加密中有特殊字符会导致异常。我可以更改此代码以某种方式加密成纯文本没有特殊字符。如何仅将文本加密为纯文本字符串

protected static byte[] encrypt(String text) 
    { 
     try 
     { 
      String key = "6589745268754125"; 
      // Create key and cipher 
      Key aesKey = new SecretKeySpec(key.getBytes(), "AES"); 
      Cipher cipher = Cipher.getInstance("AES"); 
      // encrypt the text 
      cipher.init(Cipher.ENCRYPT_MODE, aesKey); 
      byte[] encrypted = cipher.doFinal(text.getBytes()); 
      return encrypted; 
     } 
     catch(Exception ex) 
     { 
      WriteLog("Encryption Failed"); 
      WriteLog(ex.getMessage()); 
      return null; 
     } 
    } 

protected static String decrypt(byte[] pass) 
{ 
    try 
    { 
     String key = "6589745268754125"; 
     // Create key and cipher 
     Key aesKey = new SecretKeySpec(key.getBytes(), "AES"); 
     Cipher cipher = Cipher.getInstance("AES"); 
     // decrypt the text 
     cipher.init(Cipher.DECRYPT_MODE, aesKey);   
     String decrypted = new String(cipher.doFinal(pass));   
     return decrypted; 
    } 
    catch(Exception ex) 
    { 
     WriteLog("Encryption Failed");  
     WriteLog(ex.getMessage()); 
     return null; 
    } 
} 

异常消息称“由于最后一个块未正确填充” javax.crypto.BadPaddingException:鉴于最终块未正确填充

+1

什么是问题人物?什么是例外?异常在哪里? – nicomp

+0

Base64是一种编码,而不是加密。如果您想要加密字节的纯文本表示,base64是对其进行编码的好方法。 – shmosel

+0

我知道,我试图通过编码来获得,但现在我要做的加密 – Moon

回答

0

问题是填充。我曾使用AES/CBC/NoPadding并确保我的字符串是16个字节的倍数。所以除了改变ecryption和解密,我不得不添加两种方法。一个将\0即隐式空终止符添加到文本的末尾以使其成为16的倍数,并且在解密后将其移除。所以最终版本就是这样。

public class crypto { 

    static String IV = "AAAAAAAAAAAAAAAA"; 
    static String plaintext = "my non padded text"; 
    static String encryptionKey = "abcdef"; 

    public static void main(String[] args) 
    { 
     byte[] cipher = encrypt(plaintext); 
     String decrypted = decrypt(cipher); 
    } 

    protected static String covertto16Byte(String plainText) 
    { 
     while(plainText.length()%16 != 0) 
      plainText += "\0";   
     return plainText; 
    } 

    protected static String removePadding(String plainText) 
    { 
     return plainText.replace("\0",""); 
    } 

    protected static byte[] encrypt(String plainText) 
    { 
     try 
     { 
      String _plaintText_16 = covertto16Byte(plainText); 
      Cipher cipher = Cipher.getInstance("AES/CBC/NoPadding", "SunJCE"); 
      SecretKeySpec key = new SecretKeySpec(encryptionKey.getBytes("UTF-8"), "AES"); 
      cipher.init(Cipher.ENCRYPT_MODE, key,new IvParameterSpec(IV.getBytes("UTF-8"))); 
      return cipher.doFinal(_plaintText_16.getBytes("UTF-8")); 
     } catch (Exception ex) 
     { 
      //catch mechanism 
      return null; 
     } 
    } 

    protected static String decrypt(byte[] cipherText) 
    { 
     try 
     { 
      Cipher cipher = Cipher.getInstance("AES/CBC/NoPadding", "SunJCE"); 
      SecretKeySpec key = new SecretKeySpec(encryptionKey.getBytes("UTF-8"), "AES"); 
      cipher.init(Cipher.DECRYPT_MODE, key,new IvParameterSpec(IV.getBytes("UTF-8"))); 
      return removePadding(new String(cipher.doFinal(cipherText), "UTF-8")); 
     } catch (Exception ex) 
     { 
      //catch mechanism 
      return null; 
     } 
    }  
} 
0

你应该Base64编码加密的内容。顺便说一句,这是通常的技巧。

我猜客户端的问题不是Base64格式本身,但事实表明,Base64不是(强大的)加密。

1

如果客户端不喜欢Base64,请尝试Base32或Base16(= hex)。它们不太常见,但可以很好地定义Base64的替代品。

您可能还会发现客户端不希望您使用Base64的原因。

+0

客户没有按不想编码,他们想加密,我对加密一无所知。一旦输入到文本文件中,我基本上必须加密密码。我捡起来,编码并保存。稍后使用编码密码。 – Moon

+0

如果只是为了检查登录到系统而保存密码,然后用拉伸和盐对其进行哈希处理,则不要进行加密。如果密码被保存在不同的系统上使用,则需要检索实际密码,然后使用AES/CBC/PKCS7对其进行加密,并为每个密码使用单独的IV。在这里查看关于AES的其他答案,并再次询问您是否需要帮助。 – rossum

1

所以,基本上你不知道加密和有客户要加密

OK,快速平视的问题:

编码:将输入到持有相同信息的输出,但在另一个代表性...例如:1,2,3 - > A,b,C

,你可以看到输出看起来不同,但拥有相同的信息

请注意,没有任何秘密信息是必要的编码/解代码

加密:看起来乍看相似,但在这里,你需要一些秘密......加密需要2个输入...秘密和输入数据

得到的输出可以被解密,但只有当你有相应的秘密

如果你的客户想要你加密一些东西,确保这个东西可以表示为字节......加密一个字符串......不好...加密一个字符串已被转换成<在此处插入任意字节编码,例如unicode> ... ok

e ncryptions通常处理的字节(我们不关心这里的历史密码)

,当你决定一个加密/加密器,你要知道,基本上有2个不同的组:对称的和不对称

对称的:相同的密钥(阅读的秘密)您使用加密,将需要解密

不对称:有由公共和私人部分(公钥/私钥)的密钥对公共部分用于加密,私有部分用于解密...是没有意义的,除非你有需要交换密钥

各方

不对称加密通常用于加密解密密钥对称的密码,因为他们是缓慢的,而对称的密码通常是FAST

不对称密码不打算加密大量数据

对称的密码被用于大量数据

,如果你的目标只是保持它周围铺设在硬盘加密时的信息,一个对称的密码是你想要

什么

你需要一个密钥加密操作......还有......你将有问题的地方来存放它...所以如果可以的话,让用户输入一个足够复杂的密码...使用密码和一个称为PBKDF2的函数,并具有足够高的迭代次数(足够高=增加这个数字,直到过程需要几秒钟,如果你只在启动时需要这个数字,或者直到你的用户开始抱怨延迟)密码。

使用该密钥的AES在GCM模式(对称的密码)

密会想要的东西称为IV或初始化向量...

IV是没有秘密,你可以在前面加上这个东西你密文作为明文信息 的IV必须是您的密码中的一个块的大小,所以在AES 128位的情况下= 16字节 所以加密时你的IV是一个16字节的(唯一的)随机数(意味着你可能不会使用静脉注射两次或更多次:坚持使用的静脉注射,当获得新注射时,检查它是否已经存储,如果是,则开始IV生成,如果没有,存储它,然后使用i T)

解密时,阅读您的文件(第16字节)预谋明文IV

,如果你只是想在磁盘上存储的密文,记录到一个二进制文件

如果文件必须仅包含可打印的文本,在将字节写入文件之前应用像base16/32/64这样的编码,并在解密之前将其解码为字节数组(除非您的数据太大,否则您将不得不查找/写入数据流包装,将添加/剥除编码你)

+0

好摘要。需要注意的是,对于每个使用相同密钥加密的消息,IV **必须是唯一且不可预测的。 AES-GCM本质上是具有伽罗瓦功能的CTR模式以提供认证标签,并且使用具有重复的IV/nonce的CTR绝对破坏了安全性。 – Andy

+0

这是“随机数”的意思,但是,我想我应该明确指出 – DarkSquirrel42

相关问题