如何在Java中加密URL请求参数值以在通过电子邮件发送的链接中使用

拉胡尔·萨胡(Rahul Sahu)

我面临一个与加密url请求参数值有关的问题。我的场景是,我正在通过电子邮件向用户发送一个超链接,并且我想隐藏包含用户数据的url。网址包含我通过struts应用程序中的请求对象访问的数据。和使用EL在jsp页面上使用的相同值。那么,我该如何加密数据以及如何在jsp页面和struts上进行维护呢?

下面的代码我用于加密和解密数据...但是如果我加密我的请求参数值,那么我如何在jsp上获得解密的值?

import java.security.Key;

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

import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder;

@SuppressWarnings("restriction")
public class EncryptDecrypt {

    private static final String ALGO = "AES";
    private static final byte[] keyValue = new byte[] { 'T', 'h', 'e', 'B',
            'e', 's', 't', 'S', 'e', 'c', 'r', 'e', 't', 'K', 'e', 'y' };

    public static String encrypt(String Data) throws Exception {
        Key key = generateKey();
        Cipher c = Cipher.getInstance(ALGO);
        c.init(Cipher.ENCRYPT_MODE, key);
        byte[] encVal = c.doFinal(Data.getBytes());
        String encryptedValue = new BASE64Encoder().encode(encVal);
        return encryptedValue;
    }

    public static String decrypt(String encryptedData) throws Exception {
        Key key = generateKey();
        Cipher c = Cipher.getInstance(ALGO);
        c.init(Cipher.DECRYPT_MODE, key);
        byte[] decordedValue = new BASE64Decoder().decodeBuffer(encryptedData);
        byte[] decValue = c.doFinal(decordedValue);
        String decryptedValue = new String(decValue);
        return decryptedValue;
    }

    private static Key generateKey() throws Exception {
        Key key = new SecretKeySpec(keyValue, ALGO);
        return key;
    }

}
B队

您可以使用任何喜欢的加密方案,因为您是将已经加密的数据发送给用户,然后再次对其进行处理。您甚至不需要为此使用公共/私有密钥方法。

https://stackoverflow.com/questions/4319496/how-to-encrypt-and-decrypt-data-in-java

在通过电子邮件链接发送数据之前,只需对数据进行加密-然后在取回数据时再次对其进行解密。


链接的问题已被删除,我尝试不删除它,但如果没有,这里是内容。所有归功于写它的ayaylor。

除非您有非常不同寻常的要求,否则Java将拥有您所需的大多数加密工具。

对称加密

对称加密使用相同的密钥进行加密和解密。在Java中,使用的实例javax.crypto.Cipher

加密和解密

在适当的模式下初始化密码,然后调用updatedoFinal方法进行加密或解密。例子:

import java.security.*;
import javax.crypto.*;

Cipher aes = Cipher.getInstance("AES/ECB/PKCS5Padding");
aes.init(Cipher.ENCRYPT_MODE, key);
byte[] ciphertext = aes.doFinal("my cleartext".getBytes());

aes.init(Cipher.DECRYPT_MODE, key);
String cleartext = new String(aes.doFinal(ciphertext));

创建密钥

密码的密钥应为的实例javax.crypto.spec.SecretKeySpecAES特别要求其密钥的创建必须精确地使用128位(16字节)。

一种获取所需字节数的简单方法是采用可变长度的密码短语,并使用java.security.MessageDigest诸如SHA1之类的方法对其进行哈希处理例如:

import java.security.*;
import javax.crypto.spec.*;

String passphrase = "correct horse battery staple";
MessageDigest digest = MessageDigest.getInstance("SHA");
digest.update(passphrase.getBytes());
SecretKeySpec key = new SecretKeySpec(digest.digest(), 0, 16, "AES");

创建密钥的更好方法是使用带有盐的SecretKeyFactory:

byte[] salt = "choose a better salt".getBytes();
int iterations = 10000;
SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1");
SecretKey tmp = factory.generateSecret(new PBEKeySpec(passphrase.toCharArray(), salt, iterations, 128));
SecretKeySpec key = new SecretKeySpec(tmp.getEncoded(), "AES");

PBKDF2是一种专门设计用于从密码生成密钥的算法,该算法被认为比简单的SHA1哈希更安全。盐确保您的加密不会与使用相同密钥和明文的其他加密匹配,并有助于防止字典攻击。迭代值是一个可调参数。更高的值使用更多的计算能力,使暴力攻击更加困难。

初始化向量

正如评论中指出的那样,欧洲央行几乎从来都不是在实践中使用的好模式。要使用CBC等更好的模式,您需要提供并保留一个初始化向量。

使用CBC模式加密时,Java将自动生成一个随机初始化向量。为了以后能够解密,您需要将其与密文一起保存:

Cipher aes = Cipher.getInstance("AES/CBC/PKCS5Padding");
aes.init(Cipher.ENCRYPT_MODE, key);
byte[] ciphertext = aes.doFinal("my cleartext".getBytes());
byte[] iv = aes.getIV();

解密时,将其Cipher.init()作为参数传递给方法:

Cipher aes = Cipher.getInstance("AES/CBC/PKCS5Padding");
aes.init(Cipher.DECRYPT_MODE, key, new IvParameterSpec(iv));
String cleartext = new String(aes.doFinal(ciphertext));

非对称加密

非对称加密(也称为公共密钥加密)使用密钥对。密钥的一部分用于加密,另一部分用于解密。这使您可以公开加密密钥,从而允许任何人生成消息,只有您(私有解密密钥的持有者)可以阅读。或者,您可以使用私钥进行加密,该私钥对于数字签名很有用。

加密和解密

与对称加密一样,请使用的实例javax.crypto.Cipher

import java.security.*;

Cipher rsa = Cipher.getInstance("RSA/ECB/PKCS1Padding");
rsa.init(Cipher.ENCRYPT_MODE, publicKey);
byte[] ciphertext = rsa.doFinal("my cleartext".getBytes());

rsa.init(Cipher.DECRYPT_MODE, privateKey);
String cleartext = new String(rsa.doFinal(ciphertext));

生成和存储密钥

在这种情况下,键将是java.security.PublicKey和的实例java.security.PrivateKey生成一对新的:

import java.security.*;

KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");
KeyPair keyPair = keyPairGenerator.generateKeyPair();
PublicKey publicKey = keyPair.getPublic();
PrivateKey privateKey = keyPair.getPrivate();

公钥和私钥也可以转换为字节数组以进行存储和传输:

import java.security.*;
import java.security.spec.*;

KeyFactory keyFactory = KeyFactory.getInstance("RSA");
byte[] publicKeyBytes = publicKey.getEncoded();
KeySpec keySpec = new X509EncodedKeySpec(publicKeyBytes);
PublicKey keyFromBytes = keyFactory.generatePublic(keySpec);

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

如何在Laravel 5中使用队列通过电子邮件发送密码重置链接

如何在通过电子邮件表格发送的电子邮件中创建响应链接?

如何在 CodeIgniter 中使用自己的电子邮件库通过电子邮件库发送附件

如何在Python中使用smtplib通过电子邮件发送.html文件

如何在Outlook 2013表单中使用组合框和单选按钮通过电子邮件发送数据

如何在python3中使用smtplib通过电子邮件发送变量值?

如何使用MFMailComposeViewContoller通过电子邮件发送pdf?

如何使用Intent拍照并通过电子邮件发送

如何在Java中通过电子邮件从数据库发送数据(表)?

通过电子邮件发送的奇怪的cmd加密脚本

使用我的GPG公钥发送电子邮件:尝试了解如何加密PDF,我将通过电子邮件发送

使用金字塔通过POST请求通过电子邮件发送上传的文件

如何在不覆盖选项卡内容的情况下使用小书签通过电子邮件发送到当前页面的链接?

通过电子邮件发送URL方案

如何通过电子邮件发送的链接登录asp.net应用程序

如何通过电子邮件发送保存的 CSV 文件或在 Android 中使用 Google Drive 上传?

如何在人们提交电子邮件时通过电子邮件发送优惠券代码

如何通过电子邮件从特定区域发送屏幕?

如何通过电子邮件发送数据

如何通过电子邮件发送Xcode项目

如何通过电子邮件发送$ _SESSION变量

如何通过电子邮件发送python代码输出?

使用crontab通过电子邮件发送备份

使用PHP通过电子邮件发送HTML表单

通过电子邮件发送图像

通过电子邮件发送PDF

通过电子邮件发送评级

如何在TYPO3中上传PDF文件并通过电子邮件发送?

如何在android中压缩文件夹并通过电子邮件发送