【问题标题】:How to encrypt and decrypt URl parameter in java?如何在java中加密和解密URl参数?
【发布时间】:2011-03-11 20:40:46
【问题描述】:

如何在java中加密和解密URl参数而没有'/,&,=?'之类的html字符

import java.io.UnsupportedEncodingException;
import java.security.spec.AlgorithmParameterSpec;
import java.security.spec.KeySpec;

import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.PBEKeySpec;
import javax.crypto.spec.PBEParameterSpec;

public class DesEncrypter {

    Cipher ecipher;
    Cipher dcipher;

    byte[] salt =  {
            (byte)0xA9, (byte)0x9B, (byte)0xC8, (byte)0x32,
            (byte)0x56, (byte)0x35, (byte)0xE3, (byte)0x03
        };

    int iterationCount = 3;

    public DesEncrypter(String passPhrase) {

        try{

            KeySpec keySpec = new PBEKeySpec(passPhrase.toCharArray(), salt, iterationCount);
            SecretKey key = SecretKeyFactory.getInstance("PBEWithMD5AndDES").generateSecret(keySpec);

            ecipher = Cipher.getInstance(key.getAlgorithm());
            dcipher = Cipher.getInstance(key.getAlgorithm());

            AlgorithmParameterSpec paramSpec = new PBEParameterSpec(salt, iterationCount);

            ecipher.init(Cipher.ENCRYPT_MODE, key, paramSpec);
            dcipher.init(Cipher.DECRYPT_MODE, key, paramSpec);

        } catch (java.security.InvalidAlgorithmParameterException e){
        } catch (java.security.spec.InvalidKeySpecException e){
        } catch (javax.crypto.NoSuchPaddingException e){
        } catch (java.security.NoSuchAlgorithmException e){
        } catch (java.security.InvalidKeyException e){
        }
    }

    public String encrypt(String str){

        try{

            byte[] utf8 = str.getBytes("UTF8");
            byte[] enc  = ecipher.doFinal(utf8);

            return new sun.misc.BASE64Encoder().encode(enc);

        } catch (javax.crypto.BadPaddingException e){
        } catch (IllegalBlockSizeException e){
        } catch (UnsupportedEncodingException e){
        }

        return null;
    }

    public String decrypt(String str){

        try{

            byte[] dec = new sun.misc.BASE64Decoder().decodeBuffer(str);
            byte[] utf8 = dcipher.doFinal(dec);

            return new String(utf8,"UTF8");

        } catch (javax.crypto.BadPaddingException e){
        } catch (IllegalBlockSizeException e){
        } catch (UnsupportedEncodingException e){
        } catch (java.io.IOException e){
        }

        return null;
    }

}

我的代码如上,我得到了加密结果:6puu4YjzScxHsv9tI/N92g==
在上面的输出中,由于反斜杠,我得到了我想要避免的错误。

【问题讨论】:

  • 这真是个坏主意。你能告诉我们为什么你想加密它们吗?您要么想要使用 TLS 来加密服务器和客户端之间的整个通信,要么一开始就不提供应该保密的信息。
  • 天哪!永远不要写空的catch 块!您的方法只会返回 null,而您将不知道出了什么问题!把e.printStackTrace()放在那里至少!

标签: java spring encryption spring-security


【解决方案1】:

代替

        byte[] utf8 = str.getBytes("UTF8");
        byte[] enc  = ecipher.doFinal(utf8);
        return new sun.misc.BASE64Encoder().encode(enc);

加密后使用Apache Commons URL Safe 64 bit encoder进行编码。

Base64.encodeBase64URLSafeString(enc);

解密前解码:

Base64.decodeBase64(dec)

请注意,这是 ENCODER 不是加密器。但字符串是 URL 安全的。


理想情况下,您应该始终使用 URL Encoder 对您的 URL 进行编码,这将确保对特殊字符进行编码。因此,即使您的 URL 包含受限制的字符,它也是安全的。

【讨论】:

  • 我无法想象为什么这个答案被标记为正确。 OP 要求加密,而不是更好的 base64 编码。
  • @EJP -- 你应该更仔细地阅读问题和答案。加密结果字节数组。当 OP 以 64-base 编码时,它返回对 URL 不安全的等效字符串。他想要一种安全地转换为 Base64 的技术。我知道编码和加密之间的区别。我在答案中提到了它。 OP具有误导性。您应该更好地查看我编辑的问题的修订。但是当更新问题时,我意识到他需要一个安全的编码。它不能证明投反对票是合理的。
  • 这里的问题是是否阅读了这个问题。这是关于加密的。他已经对结果进行base64编码。您在这里展示的只是另一种方法。它没有回答他最初的问题。并且 decodeBase64() 不会解密,这与你上面写的相反。
  • @EJP “他已经对结果进行了 base64 编码”——是的,这就是问题所在。结果对于 URL 来说是不安全的!他要么需要使用 URLEncoder 对 URL 进行编码,要么将加密的 Byte 数组转换为 URL 安全字符串。这就是我的解决方案的用武之地。而且,我同意答案中提到的 decrypt 在上下文中是“在解密之前执行以下操作”,但因为我没有提到上下文。 Descrypt 不合适。
猜你喜欢
  • 2015-05-04
  • 2013-11-18
  • 2018-04-21
  • 2011-12-06
  • 1970-01-01
  • 1970-01-01
  • 2020-12-18
  • 2011-02-27
  • 2017-02-03
相关资源
最近更新 更多