我面临一个与加密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;
}
}
您可以使用任何喜欢的加密方案,因为您是将已经加密的数据发送给用户,然后再次对其进行处理。您甚至不需要为此使用公共/私有密钥方法。
https://stackoverflow.com/questions/4319496/how-to-encrypt-and-decrypt-data-in-java
在通过电子邮件链接发送数据之前,只需对数据进行加密-然后在取回数据时再次对其进行解密。
链接的问题已被删除,我尝试不删除它,但如果没有,这里是内容。所有归功于写它的ayaylor。
除非您有非常不同寻常的要求,否则Java将拥有您所需的大多数加密工具。
对称加密使用相同的密钥进行加密和解密。在Java中,使用的实例javax.crypto.Cipher
。
在适当的模式下初始化密码,然后调用update
和doFinal
方法进行加密或解密。例子:
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.SecretKeySpec
。AES特别要求其密钥的创建必须精确地使用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] 删除。
我来说两句