spring mvc 对 URL 参数进行加密和编码

2024-03-28

我正在编写一个 Spring mvc 应用程序,它需要发送一封包含链接和加密参数的电子邮件。用户将单击该链接,我需要解密新页面中的参数。因此,我正在编写一个 util 类来加密和解密以及对参数进行编码和解码。

当我运行我的独立java类(用于测试)时 - 当调用解密时我收到以下错误(加密、编码、解码工作正常)。

java.security.InvalidAlgorithmParameterException: Wrong IV length: must be 16 bytes long
    at com.sun.crypto.provider.CipherCore.init(CipherCore.java:430)
    at com.sun.crypto.provider.AESCipher.engineInit(AESCipher.java:217)
    at javax.crypto.Cipher.implInit(Cipher.java:791)
    at javax.crypto.Cipher.chooseProvider(Cipher.java:849)
    at javax.crypto.Cipher.init(Cipher.java:1348)

我的班级在下面

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.ObjectInput;
import java.io.ObjectInputStream;
import java.io.ObjectOutput;
import java.io.ObjectOutputStream;
import java.net.URLEncoder;
import java.security.MessageDigest;
import java.security.SecureRandom;
import java.util.HashMap;
import java.util.Map;

import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;


import org.apache.commons.codec.binary.Base64;

public class TestEncryptionEncode2 {

    private String keyString = "asdfgh";

    public static void main(String[] args) throws Exception {
         TestEncryptionEncode2 api = new TestEncryptionEncode2();

         String input = "abcdwer.comq1234";

        try {       
            String[] encrypted = api.encryptObject(input);  
            // url may differ.. based upon project initial context
            System.out.println("http://localhost:8080/view?d="+encrypted[0]+"&v="+encrypted[1]);

                        Object obj = api.decryptObject(encrypted[0], encrypted[1]);
                        System.out.println("Object Decrypted: "+obj.toString());

        }catch(Exception e) {
            //logger.debug("Unable to encrypt view id: "+id, e);
                    e.printStackTrace();
        }   

                System.out.println("DONEE ");

     }

    private String[] encryptObject(Object obj) throws Exception {
        ByteArrayOutputStream stream = new ByteArrayOutputStream();
        ObjectOutput out = new ObjectOutputStream(stream);
        try {
            // Serialize the object         
            out.writeObject(obj);       
            byte[] serialized = stream.toByteArray();

                        System.out.println("serialized "+serialized[0]);

            // Setup the cipher and Init Vector
            Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
            byte[] iv = new byte[cipher.getBlockSize()];

                System.out.println("cipher.getBlockSize() "+cipher.getBlockSize());
                System.out.println("iv.length "+iv.length);


            new SecureRandom().nextBytes(iv);
            IvParameterSpec ivSpec = new IvParameterSpec(iv);

            // Hash the key with SHA-256 and trim the output to 128-bit for the key
            MessageDigest digest = MessageDigest.getInstance("SHA-256");
            digest.update(keyString.getBytes());
            byte[] key = new byte[16];
            System.arraycopy(digest.digest(), 0, key, 0, key.length);
            SecretKeySpec keySpec = new SecretKeySpec(key, "AES");

            // encrypt
            cipher.init(Cipher.ENCRYPT_MODE, keySpec, ivSpec);

            // Encrypt & Encode the input
            byte[] encrypted = cipher.doFinal(serialized);       
            byte[] base64Encoded = Base64.encodeBase64(encrypted);
            String base64String = new String(base64Encoded);
            String urlEncodedData = URLEncoder.encode(base64String,"UTF-8");

            // Encode the Init Vector
            byte[] base64IV = Base64.encodeBase64(iv);
            String base64IVString = new String(base64IV);
            String urlEncodedIV = URLEncoder.encode(base64IVString, "UTF-8");

                System.out.println("urlEncodedData.length "+urlEncodedData.length());
                System.out.println("urlEncodedIV.length "+urlEncodedIV.length());


            return new String[] {urlEncodedData, urlEncodedIV};
        }finally {
            stream.close();
            out.close();
        }
    }

    /**
     * Decrypts the String and serializes the object
     * @param base64Data
     * @param base64IV
     * @return
     * @throws Exception
     */
    public Object decryptObject(String base64Data, String base64IV) throws Exception {

            System.out.println("decryptObject "+base64Data);
            System.out.println("decryptObject "+base64IV);

        // Decode the data
        byte[] encryptedData = Base64.decodeBase64(base64Data.getBytes()); 

        // Decode the Init Vector
        byte[] rawIV = Base64.decodeBase64(base64IV.getBytes()); 
        System.out.println("rawIV "+rawIV.length);
                for (int i=0;i < rawIV.length;i++ ){
                    System.out.println("---------"+rawIV[i]);
                }
        // Configure the Cipher
        Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
        IvParameterSpec ivSpec = new IvParameterSpec(rawIV); 
        MessageDigest digest = MessageDigest.getInstance("SHA-256");
        digest.update(keyString.getBytes());
        byte[] key = new byte[16];
        System.arraycopy(digest.digest(), 0, key, 0, key.length);
        SecretKeySpec keySpec = new SecretKeySpec(key, "AES");
        cipher.init(Cipher.DECRYPT_MODE, keySpec, ivSpec); //////////////////////////////This is the error line

        // Decrypt the data..
        byte[] decrypted = cipher.doFinal(encryptedData);

        // Deserialize the object       
        ByteArrayInputStream stream = new ByteArrayInputStream(decrypted);
        ObjectInput in = new ObjectInputStream(stream);
        Object obj = null;
        try {
            obj = in.readObject(); 
                        System.out.println("objobj "+obj);

        }
                catch(Exception e) {
            //logger.debug("Unable to encrypt view id: "+id, e);
                    e.printStackTrace();
        }finally {
            stream.close();
            in.close();
        }
        return obj;
    }


}

这是错误行 - cipher.init(Cipher.DECRYPT_MODE, keySpec, ivSpec);

我还需要添加什么吗?谢谢。

EDIT:谢谢,谢谢,成功了。出于某种原因,我以为我已经在解码数据了。

EDIT2:如果要解码的文本中包含 +,则解码后的文本将包含空格而不是 +。所以解密的时候我必须把所有的空格都用+替换掉。希望这对某人有帮助。


解密过程应该是加密过程的逆过程。

在加密中你正在做的事情URL在将其返回给用户之前进行编码。所以在解密过程中必须先进行URL解码。

这是完整的解密过程URL解码:

public Object decryptObject(String base64Data, String base64IV) throws Exception {

        System.out.println("decryptObject " + base64Data);
        System.out.println("decryptObject " + base64IV);

        String urlDecodedData=URLDecoder.decode(base64Data,"UTF-8");
        // Decode the data
        byte[] encryptedData = Base64.decodeBase64(urlDecodedData.getBytes());

        String urlDecodedIV=URLDecoder.decode(base64IV,"UTF-8");
        // Decode the Init Vector
        byte[] rawIV = Base64.decodeBase64(urlDecodedIV.getBytes());
        System.out.println("rawIV " + rawIV.length);

        // Configure the Cipher
        Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
        IvParameterSpec ivSpec = new IvParameterSpec(rawIV);
        MessageDigest digest = MessageDigest.getInstance("SHA-256");
        digest.update(keyString.getBytes());
        byte[] key = new byte[16];
        System.arraycopy(digest.digest(), 0, key, 0, key.length);
        SecretKeySpec keySpec = new SecretKeySpec(key, "AES");
        cipher.init(Cipher.DECRYPT_MODE, keySpec, ivSpec); //////////////////////////////This is the error line

        // Decrypt the data..
        byte[] decrypted = cipher.doFinal(encryptedData);

        // Deserialize the object       
        ByteArrayInputStream stream = new ByteArrayInputStream(decrypted);
        ObjectInput in = new ObjectInputStream(stream);
        Object obj = null;
        try {
            obj = in.readObject();
            System.out.println("objobj " + obj);

        } catch (Exception e) {
            //logger.debug("Unable to encrypt view id: "+id, e);
            e.printStackTrace();
        } finally {
            stream.close();
            in.close();
        }
        return obj;
    }
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

spring mvc 对 URL 参数进行加密和编码 的相关文章

  • war文件可以部署在任何服务器上吗?

    如果这个问题很愚蠢 请原谅我 假设我使用 Spring 框架和 MS SQL Server 数据库以及 WebSphere 应用程序服务器开发一个 J2EE Web 应用程序 我后来为此应用程序创建了一个 WAR 文件 我可以在不更改代码的
  • 删除列表视图项目之间的间距

    我正在尝试在 Android 中制作一个包含图像的 ListView 我希望图像在列表中彼此相对 但我似乎无法消除间距 这是我的 listview xml
  • 使用递归查找数组中的最大值

    对于我被要求解决的问题之一 我使用 for 循环找到了数组的最大值 所以我尝试使用递归来找到它 这就是我想到的 public static int findMax int a int head int last int max 0 if h
  • JFace DialogCellEditor:如何使按钮始终出现?

    我用的是JFaceDialogCellEditor在 JFace 的一行单元格中显示一个按钮TableViewer激活时会触发一个对话框 此行为适用于以下代码 但仅当显式选择托管按钮的表的单元格时才会显示该按钮 public class C
  • 在远程 Tomcat 上自动部署 Java 应用程序

    我希望能够自动将 Java 应用程序部署到 tomcat 服务器 现在的情况 正在 Eclipse 中开发 Java 项目 Tomcat 服务器在另一台机器上运行 提供该项目的 WAR 文件 我的目标 可以轻松编译项目并将其部署到远程 To
  • Ant 复制文件而不覆盖

    Is there any command in ant to copy files from one folder structure to another without checking the last modified date t
  • Java,ASM:如何从ASM InsnNode获取操作码名称和TagValue?

    我正在研究一些类文件分析 并且正在研究使用 ASM 来读取类 在 Javap 中 操作码以及 tagName 和 tagValue 是内联打印的 但在每个 AbstractInsnNode 中 我只看到 int 的字段 而不是 tagVal
  • JUnit 测试 Spymemcached 客户端

    我有一个类围绕spymemcached 客户端 我想编写一些JUnit 测试来测试getValue 和addKey 方法是否有效 问题是无法从测试服务器访问spymemcached 服务器 所以我想这里需要一些模拟 我的简化类看起来像这样
  • 如何在 Apache POI 中获取 Excel 空白单元格值?

    我有一个巨大的 Excel 文件 其中包含大量列 如下所示 Column1 Column2 Column3 Column4 Column5 abc def ghi mno pqr 这是我编写的用于打印这些值的代码 try FileInput
  • Spring数据异常处理

    我正在使用 Spring Data JPA 开发一个项目 我需要处理 JpaRepository 方法调用中的一些异常 在下面的代码中 我需要拦截主键违规错误 但无法直接捕获异常 就我而言 当发生此类异常时 存储库层 JpaReposito
  • 通常可重用的注释或公共注释?

    有没有常用的注释 类似于 commons lang 如果没有 您是否见过在任何开源应用程序开发中有效使用注释 不是内置注释 的情况 我记得 Mifos 用它来进行交易 Mohan i think 休眠验证器 http www hiberna
  • 将 JSON 与嵌套数组和 json 进行比较(数组顺序无关紧要)

    你好 我正在尝试比较java中的两个json 每个键可以包含一个json对象或json对象数组 并且它们中的每个也可以是数组或json 这是 Json 的示例 id 123123asd123 attributes name apps val
  • 有丰富的领域模型示例吗? [关闭]

    Closed 此问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 我正在寻找一个简单的示例来说明使用富域模型的好处 理想情况下 我想要一个之前和之后的代码列表 应该尽可能
  • 如何在java中将ojalgo稀疏数组存储到文件中?

    我目前有一个 SparseStore 矩阵 我在其中执行大量计数和计算 我想将其存储到文件中 以便以后可以重复使用它 而无需重新执行之前的所有计算 我尝试了 Java 中的基本序列化 ObjectOutputStream outputStr
  • 在 ant 脚本中包含外部 JAR 时出错

    这是我第一次尝试编写 ANT 脚本 这是我使用 Spring 构建的简单 Hello World 应用程序的 build xml
  • 用 org.Json 解析 Java 中的 JSON?

    我在这方面遇到了很多麻烦 我正在尝试进行更新 并且正在使用从 url 返回此内容的 api JSON downloadUrl URL fileName Name gameVersion Version name Name projectId
  • 使用 getPathMatcher 的全局模式

    从 OCP 考试的 Kathy Sierra Bert Bates 书中我找到了以下代码 public class FileTest public static void matches Path path String glob Path
  • 在可序列化 Java 类中使用记录器的正确方法是什么?

    我有以下 doctored 我正在开发的系统中的类以及Findbugs http findbugs sourceforge net 正在生成一个SE BAD FIELD http findbugs sourceforge net bugDe
  • 在 Spring 中以编程方式解析 AliasFor 注释值

    我有一个注释 Target ElementType TYPE Retention RetentionPolicy RUNTIME public interface A Class value 这是在课堂上使用的 B D class publ
  • Java - 全局、可重用的加载对话框

    我正在尝试实现一个全局加载对话框 我想调用一些静态函数来显示对话框和一些静态函数来关闭它 与此同时 我正在主线程或子线程中做一些工作 我尝试以下操作 但对话框没有更新 最后一次 在再次隐藏之前 它会更新 private static Run

随机推荐

  • 模拟器:模拟器:警告:无法连接到代理:::1:8080:未知错误! - 安卓

    模拟器 模拟器 警告 无法连接到代理 1 8080 未知错误 安卓 更新后我收到此错误Android Studio 2 3 2 to Android Studio 3 0 canary 2 由于此错误 互联网无法在模拟器中运行 Edit 我
  • C 中任意数量的空格分割字符串

    我有一个文件 其中每个用户名和密码都由不同数量的空格分隔 bob passowrd1 saly password2 sam password2 void parse FILE open open fopen file txt char li
  • 在r中,如何按一个因子修剪或缩尾数据

    我试图在因素 主题 的每个级别应用温莎函数 以消除极端情况 我可以将winsor函数应用于整个列 但想在主题内执行此操作 Subject RT 1 402 1 422 1 155 1 460 2 283 2 224 2 346 2 447
  • java.lang.NullPointerException:使用 QueryDsl 过滤数据时

    我正在使用 Spring data jpa 来创建服务 在下面的代码中 我使用 Querydsl 在网格上实现搜索过滤器 但对于建筑物名称 我无法过滤网格 我正进入 状态 java lang NullPointerException nul
  • Visual Studio 2008、C++ 的探查器?

    有什么好的 免费的 或者至少相当便宜的 至少适用于本机 C 的分析器 可以与 Visual Studio 2008 专业版 我在看社区版但是他们 似乎只支持 Visual Studio 2003 和 Visual Studio 2005 如
  • @NotNull 注释在 Spring boot 应用程序中不起作用

    下面是我的 DTO 课程 public class AbstractDTO extends BaseDTO private Integer createdBy JsonFormat shape JsonFormat Shape STRING
  • 如何设置子视图到窗口的视图方向

    我创建了一个 UIView 我想将视图子视图添加到 appdelegate 窗口 UIView newView UIView alloc initWithFrame CGRectMake 0 0 1048 748 AppDelegate a
  • 从列表中删除重复的子列表

    如果我有一个这样的列表 mylist 1 2 3 a c 3 4 5 1 2 3 4 5 a c 3 4 5 1 2 删除重复子列表的最佳方法是什么 现在我用this https stackoverflow com a 20462808 4
  • Docker COPY 没有这样的文件或目录

    构建 docker 映像在复制任务中失败 没有这样的文件或目录 我正在使用你好世界春天的例子 https spring io guides gs spring boot docker 从 openjdk 构建 8 jdk alpine Ru
  • Jquery 加载函数将附加到已经存在的 HTML 上

    我正在尝试进行 AJAX 调用 该调用将附加 html 即向标签之间已存在的内容添加额外的 html 这是我的加载函数的样子 我如何修改这个函数才能将其附加到类 tid list 中 提前致谢 您必须通过ajax获取数据并使用 tid li
  • 在 jQuery 中将 processData 设置为 false 会破坏我的 AJAX 请求

    我已经用谷歌搜索了一段时间 只能找到什么processData false做 我找不到经历过同样问题的人 我将 JSON 传递回服务器 并且不希望 jQuery 自动将数据转换为查询字符串 因此我将 processData 设置为 fals
  • 获取 VBScript 中变量的类型

    如何使用 VBScript 获取变量的类型 Is VarType https msdn microsoft com en us library aa263402 v vs 60 aspx你需要什么 返回一个指示变量子类型的值 Constan
  • 在区域之外的 MVC 应用程序中托管 WCF 服务

    我有一个 MVC 项目 我在根目录中添加了一个名为 WCF 的文件夹 在此文件夹中 我创建了一个名为的 WCF 服务CustomFunctions 当我尝试启动该服务时 我收到以下错误 错误 无法从中获取元数据http localhost
  • 使用 ajax 包含子行的闪亮数据表

    我正在尝试使用数据表库来实现更多自定义的闪亮效果 这是我试图做的例子 https datatables net examples api row details html https datatables net examples api
  • AfxGetAppName() 返回垃圾字符

    我的应用程序中有以下代码行 CString strAppName AfxGetAppName 有时会充满strAppName出现了垃圾字符 我不明白为什么 有人有主意吗 TIA 如果你改变的话这是可能的m pszAppName手动 在应用程
  • 将字符串列表通过管道传输到 for 循环

    我如何将列表传递给for在bash中 I tried echo some different lines for i do echo do something with i done 但这行不通 我也试图找到一个解释man但没有man fo
  • 使用 javascript 在循环内设置超时

    我正在制作一个解谜函数 它使用当前打乱顺序的一系列拼图 每个片段都有一个 id 它指向数组中的正确位置 我在要交换的部分上设置了叠加颜色 我希望在着色和交换的部分之间有一个延迟 function solvePuzzle while rezo
  • JavaScript/GSON:通过对象图动态访问 JSON 引用(循环引用)

    由于存在多个循环引用 我在通过 Google GSON 序列化 Java 对象时遇到了问题 我所有的尝试都以 StackOverflowException 结束 因为 GSON 无法处理这些循环引用 作为解决方案 我发现以下GraphAda
  • SELECT FOR UPDATE 中的数据库死锁

    我的应用程序间歇性陷入僵局 我的应用程序有 1 个表 例如 EMPLOYEE ID PK NAME SAL 并且有 2 个会话 第一节 SELECT ID NAME SAL FROM EMPLOYEE WHERE SAL SELECT MI
  • spring mvc 对 URL 参数进行加密和编码

    我正在编写一个 Spring mvc 应用程序 它需要发送一封包含链接和加密参数的电子邮件 用户将单击该链接 我需要解密新页面中的参数 因此 我正在编写一个 util 类来加密和解密以及对参数进行编码和解码 当我运行我的独立java类 用于