如何在java中加密和解密URl参数?

Vin*_*adi 2 java encryption spring spring-security

如何在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;
    }

}
Run Code Online (Sandbox Code Playgroud)

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

Nis*_*ant 11

代替

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

使用Apache Commons URL Safe 64位编码器在加密后进行编码.

Base64.encodeBase64URLSafeString(enc);
Run Code Online (Sandbox Code Playgroud)

在解密之前解码:

Base64.decodeBase64(dec)
Run Code Online (Sandbox Code Playgroud)

请注意,这是ENCODER而不是加密器.但String是URL安全的.


理想情况下,您应始终使用URL编码器对您的URL进行编码,以确保对特殊字符进行编码.因此,即使您拥有受限字符的URL,也会很安全.

  • 我无法想象为什么这个答案被标记为正确.OP请求加密,而不是更好的base64编码. (3认同)
  • @EJP - 你应该仔细阅读问题和答案.加密结果Byte数组.当OP以64-base编码时,它返回对于URL不安全的String等价物.他想要一种安全转换为Base64的技术.我知道编码和加密之间的区别.我在答案中提到了这一点.OP具有误导性.你应该更好地看到我编辑过的问题的修订版.但是当更新问题时,我意识到他需要一个安全的编码.这并不能证明投票不合理. (2认同)