`
baggioback
  • 浏览: 71561 次
  • 性别: Icon_minigender_1
  • 来自: 武汉
社区版块
存档分类
最新评论

get加密

 
阅读更多

一般我们在form提交时不要担心我们的参数会显示给用户看。

 

我们主要解决的是以get方式进行url参数传递的问题,如:

 

http://xxx.xxx.xxx.xxx/xxx/xxx.do?pId=101&imageName=processimage.jpg这样的url pId=101&imageName=processimage.jgp这样的参数如何进行加密。

 

我们采用:

 

java.net.URLEncoder.encode(Base64编码(加密字串), StringCode) 这样的方法来对url中的参数进行加密。

 

首先我们先说一下如何加密。

 

一、算法的选择:

 

对于像对url中的参数进行加密的过程,我不建议使用rsa或者是三重des这样的加密算法,主要原因在于性能和速度会受影响。

 

我建议大家使用对称加密如:DES或者是PBE算法。

 

我们在这边就使用PBEWithMD5AndDES来实现加密。

 

二、加密原理

 

对于一个纯文本,加密后它会变成一堆乱码,这堆乱码包括了许多非法字符,我们不希望把这些字符放入bean中,因此在加密完后,我们还要对加密结果进行base64编码。

 

PBE从字面上理解,它必须使用一个口令,我们不希望我们的加密过于复杂而影响页面跳转的速度,因此我们不采用口令+KEY的形式,我们这边的口令就是我们的KEY

 

因此:

 

我们的整个加密过程实现如下:

 

输入口令(KEY)--> 加密文本 --> 以base64对加密后的结果进行编码-->以java.net.URLEncoder.encode编码成浏览器可以识别的形式-->传输给接受的action

 

而解密过程如下:

 

接受的action得到参数-->以base64对结果进行解码-->得到纯加密文本-->解密-->得到解密后的值

 

三、BASE64

这边对于BASE64的原理不多说了,只说实现,目前网上有很多实现方式,有自己写的,有用sun.misc.*的,我们在这个例子里将使用javax.mail.internet.MimeUtility自带的base64编码工具。

需要引入activation.jar和mail.jar两个包。 下面是具体的实现:

Java代码  收藏代码
  1. import javax.mail.internet.MimeUtility;  
  2. public class Base64 {  
  3.  public static byte[] encode(byte[] b) throws Exception {  
  4.   ByteArrayOutputStream baos = null;  
  5.   OutputStream b64os = null;  
  6.   try {  
  7.    baos = new ByteArrayOutputStream();  
  8.    b64os = MimeUtility.encode(baos, "base64");  
  9.    b64os.write(b);  
  10.    b64os.close();  
  11.    return baos.toByteArray();  
  12.   } catch (Exception e) {  
  13.    throw new Exception(e);  
  14.   } finally {  
  15.    try {  
  16.     if (baos != null) {  
  17.      baos.close();  
  18.      baos = null;  
  19.     }  
  20.    } catch (Exception e) {  
  21.    }  
  22.    try {  
  23.     if (b64os != null) {  
  24.      b64os.close();  
  25.      b64os = null;  
  26.     }  
  27.    } catch (Exception e) {  
  28.    }  
  29.   }  
  30.  }  
  31.  public static byte[] decode(byte[] b) throws Exception {  
  32.   ByteArrayInputStream bais = null;  
  33.   InputStream b64is = null;  
  34.   try {  
  35.    bais = new ByteArrayInputStream(b);  
  36.    b64is = MimeUtility.decode(bais, "base64");  
  37.    byte[] tmp = new byte[b.length];  
  38.    int n = b64is.read(tmp);  
  39.    byte[] res = new byte[n];  
  40.    System.arraycopy(tmp, 0, res, 0, n);  
  41.    return res;  
  42.   } catch (Exception e) {  
  43.    throw new Exception(e);  
  44.   } finally {  
  45.    try {  
  46.     if (bais != null) {  
  47.      bais.close();  
  48.      bais = null;  
  49.     }  
  50.    } catch (Exception e) {  
  51.    }  
  52.    try {  
  53.     if (b64is != null) {  
  54.      b64is.close();  
  55.      b64is = null;  
  56.     }  
  57.    } catch (Exception e) {  
  58.    }  
  59.   }  
  60.  }  
  61. }  

 

 

四、加密解密工具类的实现

 

有了BASE64的工具类,下面的工作将变得简单了,编写我们的加密解密工具类吧:

 

Java代码  收藏代码
  1. import java.io.DataOutputStream;  
  2. import java.io.FileOutputStream;  
  3. import java.security.*;  
  4. import javax.crypto.*;  
  5. import javax.crypto.spec.*;  
  6. import java.util.*;  
  7. import org.apache.commons.logging.Log;  
  8. import org.apache.commons.logging.LogFactory;  
  9. public class SecurityHelper {  
  10.  protected final static Log logger = LogFactory.getLog(SecurityHelper.class);  
  11.  private final static int ITERATIONS = 20;  
  12.  public static String encrypt(String key, String plainText) throws Exception {  
  13.   String encryptTxt = "";  
  14.   try {  
  15.    byte[] salt = new byte[8];  
  16.    MessageDigest md = MessageDigest.getInstance("MD5");  
  17.    md.update(key.getBytes());  
  18.    byte[] digest = md.digest();  
  19.    for (int i = 0; i < 8; i++) {  
  20.     salt[i] = digest[i];  
  21.    }  
  22.    PBEKeySpec pbeKeySpec = new PBEKeySpec(key.toCharArray());  
  23.    SecretKeyFactory keyFactory = SecretKeyFactory  
  24.      .getInstance("PBEWithMD5AndDES");  
  25.    SecretKey skey = keyFactory.generateSecret(pbeKeySpec);  
  26.    PBEParameterSpec paramSpec = new PBEParameterSpec(salt, ITERATIONS);  
  27.    Cipher cipher = Cipher.getInstance("PBEWithMD5AndDES");  
  28.    cipher.init(Cipher.ENCRYPT_MODE, skey, paramSpec);  
  29.    byte[] cipherText = cipher.doFinal(plainText.getBytes());  
  30.    String saltString = new String(Base64.encode(salt));  
  31.    String ciphertextString = new String(Base64.encode(cipherText));  
  32.    return saltString + ciphertextString;  
  33.   } catch (Exception e) {  
  34.    throw new Exception("Encrypt Text Error:" + e.getMessage(), e);  
  35.   }  
  36.  }  
  37.  public static String decrypt(String key, String encryptTxt)  
  38.    throws Exception {  
  39.   int saltLength = 12;  
  40.   try {  
  41.    String salt = encryptTxt.substring(0, saltLength);  
  42.    String ciphertext = encryptTxt.substring(saltLength, encryptTxt  
  43.      .length());  
  44.    byte[] saltarray = Base64.decode(salt.getBytes());  
  45.    byte[] ciphertextArray = Base64.decode(ciphertext.getBytes());  
  46.    PBEKeySpec keySpec = new PBEKeySpec(key.toCharArray());  
  47.    SecretKeyFactory keyFactory = SecretKeyFactory  
  48.      .getInstance("PBEWithMD5AndDES");  
  49.    SecretKey skey = keyFactory.generateSecret(keySpec);  
  50.    PBEParameterSpec paramSpec = new PBEParameterSpec(saltarray,  
  51.      ITERATIONS);  
  52.    Cipher cipher = Cipher.getInstance("PBEWithMD5AndDES");  
  53.    cipher.init(Cipher.DECRYPT_MODE, skey, paramSpec);  
  54.    byte[] plaintextArray = cipher.doFinal(ciphertextArray);  
  55.    return new String(plaintextArray);  
  56.   } catch (Exception e) {  
  57.    throw new Exception(e);  
  58.   }  
  59.  }  

 

 

注意上面加粗的三处地方:

 private final static int ITERATIONS = 20;

 

 上面的值越大,加密越深,一般例子都以"Java安全性编程指南”这本书中的例子的值为准,设成1000,我们在这边只需要20就够了,原因就是考虑到加解密的速度问题。

 int saltLength = 12;
这是base64解码后的盐的长度,加密后再经BASE64编码后盐的长度为8,BASE64解码后盐的长度为12,至于为什么,这也是根据BASE64的原理得出的,具体可以看BASE64原理,网上很多,说得也都很简单。

 

PBEWithMD5AndDES

我们使用的是PBEWithMD5AndDES加密。

 

下面编写一个测试类

 

Java代码  收藏代码
  1. public static void main(String[] args) {  
  2.   String encryptTxt = "";  
  3.   String plainTxt = "hello oh my god";  
  4.   try {  
  5.    System.out.println(plainTxt);  
  6.    encryptTxt = encrypt("mypassword01", plainTxt);  
  7.    plainTxt = decrypt("mypassword01", encryptTxt);  
  8.    System.out.println(encryptTxt);  
  9.    System.out.println(plainTxt);  
  10.   } catch (Exception e) {  
  11.    e.printStackTrace();  
  12.    System.exit(-1);  
  13.   }  
  14.  }  
  15. }  

 

 

五、工具类在struts action中的具体使用

    

Java代码  收藏代码
  1. MyTaskDTO taskDTO = new MyTaskDTO();  
  2.     TaskInstance ti = (TaskInstance) it.next();  
  3.     taskDTO.setTaskName(ti.getName());  
  4.     taskDTO.setTaskCreateDate(sd.format(ti.getCreate()));  
  5.     taskDTO.setTaskDescr(ti.getDescription());  
  6.     /* no encrypted data */  
  7.     String taskId = String.valueOf(ti.getId());  
  8.     String tokenId = String.valueOf(ti.getToken().getId());  
  9.     processImgName = PropertyUtil.getProperty(  
  10.       Constants.BPM_PROCESS_PAYMENT_PROCESSIMAGE).toString()  
  11.       + ".jpg";  
  12.     processDefId = String.valueOf(ti.getToken()  
  13.       .getProcessInstance().getProcessDefinition().getId());  
  14.     /* encrypted data */  
  15.     taskId = EncryptUrlPara.encrypt(taskId);  
  16.     tokenId = EncryptUrlPara.encrypt(tokenId);  
  17.     processImgName = EncryptUrlPara.encrypt(processImgName);  
  18.     processDefId = EncryptUrlPara.encrypt(processDefId);  
  19.     taskDTO.setTaskId(taskId);  
  20.     taskDTO.setTokenId(tokenId);  
  21.     taskDTO.setProcessDefinitionId(processDefId);  
  22.     taskDTO.setProcessImageName(processImgName);  
  23.    

 

六、jsp页面中的encode

把上述这个bean放入request中,带到下一个jsp页面中后,在jsp页面的处理如下:

    

Jsp代码  收藏代码
  1. String processImgPath=taskDTO.getProcessImageName();  
  2.     String processDefId=taskDTO.getProcessDefinitionId();  
  3.     processImgPath=java.net.URLEncoder.encode(processImgPath,"UTF-8");  
  4.     processDefId=java.net.URLEncoder.encode(processDefId,"UTF-8");  
  5.     String showProcessImgUrl=request.getContextPath()+"/queryMyTask.do";  
  6.   <a href="<%=showProcessImgUrl%>?method=showProcessImg&processDefinitionId=<%=processDefId%>&processImgPath=<%=processImgPath%>" target="_blank"><u><span class="left_txt">查看当前进程</span></u></a>  

 

七、在接受加密参数的action中对加密的值进行解密

我们假设我们的接受的action为: queryMyTask.do,它接受一系列的参数,基中,processDefId和processImgPath是加密的。

实现如下:

Java代码  收藏代码
  1. String processImgFilePath = "";  
  2.  String processDefinitionId = (String) request.getParameter("processDefinitionId");  
  3.  processImgFilePath = (String) request.getParameter("processImgPath");  
  4.  processDefinitionId = EncryptUrlPara.decrypt(processDefinitionId);  
  5.  processImgFilePath = EncryptUrlPara.decrypt(processImgFilePath);  

 

 

需要注意的是此处不需要再decode了。

 

八、key(口令)的存放

 

因为我们这边的key就是口令,是一个文本,我们将它存放在server端的properties中,当然,我们也是加密存放的。

 

我们使用spring+jasypt1.5(java simple encrypt包)。

 

设我们有一个properties文件,其中:

security.des.key=ENC(OlO0LqELUuLOVreCtDngHaNgMcZWUyUg)

这个就是我们在encrypt和decrypt方法中用到的key.

我们不希望这个key以明文的形式设在properties中,我们对这个key再进行一次加密用的同样也是PBEWithMD5AndDES,当然因为有了spring因为有了jasypt包,因此这个过程一切是自动的。

我们使用jasypt包下的bin中自带的encrypt.bat工具:

 

encrypt input=mykey password=secret algorithm=PBEWithMD5AndDES

该命令会输出一行乱码,把这行乱码复制到properties文件中,在外层加上ENC(),如:

 

生成: OlO0LqELUuLOVreCtDngHaNgMcZWUyUg

放入properties后需要转换成: ENC(OlO0LqELUuLOVreCtDngHaNgMcZWUyUg)

 

然后在工程布署的机器上需要设一个环境变理,如:

set APP_ENCRYPTION_PASSWORD=secret   此处的值必须和上面encrypt.bat命令行中的password=后的值一样。

(linux请用export APP_ENCRYPTION_PASSWORD=secret)

 

然后配置spring,使该properties在工程被app 容器load时,自动解密,这样我们在我们的方法中直接取到该KEY时就已经是明文了(解密过程是jasypt+spring自动完成的),以下是这一步配置的详细内容:

 

 

Xml代码  收藏代码
  1. <context:component-scan base-package="jbpmweb" />  
  2.  <bean id="environmentVariablesConfiguration"  
  3.   class="org.jasypt.encryption.pbe.config.EnvironmentStringPBEConfig"  
  4.   p:algorithm="PBEWithMD5AndDES" p:passwordEnvName="APP_ENCRYPTION_PASSWORD" />  
  5.  <!-- 
  6.   The will be the encryptor used for decrypting configuration values. 
  7.  -->  
  8.  <bean id="configurationEncryptor" class="org.jasypt.encryption.pbe.StandardPBEStringEncryptor"  
  9.   p:config-ref="environmentVariablesConfiguration" />  
  10.  <bean id="propertyConfigurer"  
  11.   class="org.jasypt.spring.properties.EncryptablePropertyPlaceholderConfigurer">  
  12.   <constructor-arg ref="configurationEncryptor" />  
  13.   <property name="locations">  
  14.    <list>  
  15.     <value>classpath:xxx.properties</value>  
  16.    </list>  
  17.   </property>  
  18.  </bean>  
  19.  <!--  
  20.   Configurer that replaces ${...} placeholders with values from a  
  21.   properties file  
  22.  -->  
  23.  <context:property-placeholder location="classpath:jbpmweb.properties" />  
  24.  <bean id="commonsConfigurationFactoryBean" class="xxx.xxx.CommonsConfigurationFactoryBean"  
  25.   p:systemPropertiesModeName="SYSTEM_PROPERTIES_MODE_OVERRIDE" p:encryptor-ref="configurationEncryptor">  
  26.   <constructor-arg>  
  27.    <bean class="org.apache.commons.configuration.PropertiesConfiguration">  
  28.     <constructor-arg value="xxx.properties" />  
  29.    </bean>  
  30.   </constructor-arg>  
  31.  </bean>  
  32.    
  33.     
  34.  <bean id="propertiesConfiguration" factory-bean="&amp;commonsConfigurationFactoryBean"  
  35.   factory-method="getConfiguration"/>  

 

分享到:
评论
1 楼 kunsyliu 2014-03-07  

相关推荐

    C#winform工具模拟getpost请求,app防攻击加密源码

    【1】哪些人可以用到 1,不知道咋get、post请求的;...模拟请求串可以自己写,重点是借鉴一下加密方式,如果不会get和post的也可以翻一下里面的局部代码直接拿去用。 【4】留个 E麦 多多交流:guangxfxj圈sina.com

    URL参数加密解密(java版)

    - 加密后使用`Base64.getEncoder().encodeToString()`编码,解密前使用`Base64.getDecoder().decode()`解码。 4. **URL编码**: - 即使是Base64编码后的字符串,也可能包含URL非法字符,需要使用`java.net....

    开发通用工具 加密解密 post get请求等等

    这些工具通常涵盖多种功能,例如加密、解密、POST和GET请求等。在本文中,我们将深入探讨这些核心概念及其在实际开发中的应用。 1. **加密与解密**: - **加密**:是为了保护数据的安全,将明文转换为密文的过程。...

    加密软件漏洞评测系统 V8.9

    将打包后的文件复制到未安装加密软件的电脑上,用文件提取程序(GetFile.exe)  来提取文件,则提取出来的文件为明文文件(目前对市场上的所有文档透明加密系统均有效)。  加密软件漏洞评测系统使用方法如下: ...

    PHP 加密解密和解决URL传输问题

    PHP的`openssl_pkey_new`和`openssl_pkey_get_private`等函数可以生成和操作密钥对。 在URL传输过程中,我们通常会遇到编码问题。URL只能包含ASCII字符集的一部分,其他字符需要使用百分比编码(%xx)表示。PHP的`...

    开发通用工具 加密解密 post get请求,批量修改文件名等等

    开发通用工具 加密解密 post get请求,批量修改文件名等等开发通用工具 加密解密 post get请求,批量修改文件名等等开发通用工具 加密解密 post get请求,批量修改文件名等等开发通用工具 加密解密 post get请求,...

    加密软件漏洞评测系统

    将打包后的文件复制到未安装加密软件的电脑上,用文件提取程序(GetFile.exe)  来提取文件,则提取出来的文件为明文文件(目前对市场上的所有文档透明加密系统均有效)。  加密软件漏洞评测系统使用方法如下: ...

    jsencrypt参数前端加密c#解密

    jsencrypt 参数前端加密 C# 解密 jsencrypt 是一个 JavaScript 库,用于在客户端对数据进行加密,而 C# 则是用于在服务器端对数据进行解密的语言。以下是关于 jsencrypt 参数前端加密 C# 解密的知识点: 1. 前端...

    微信小程序CBC加密工具

    微信小程序CBC加密工具是一款专为小程序开发者设计的实用软件,旨在简化数据加密的过程,提高应用程序的安全性。在当今数字化时代,数据安全愈发重要,尤其是在移动应用领域,如微信小程序这样的轻量级应用平台。CBC...

    凯撒加密和置换加密程序实现加解密 C语言

    1. **获取密钥**:通过`getkey()`函数输入密钥`k`,并计算出密钥长度`kl`。 2. **处理密钥**:利用`getkt()`函数对密钥进行排序处理,生成一个表示字符位置的新数组`kn`。 3. **获取明文**:通过`getp()`函数读入待...

    C# 对称法加密、解密dataset,算法使用了二进制流得方式进行加密、解密,提高效率

    在C#中,可以使用Aes.Create()方法创建一个新的AES实例,然后通过GetKey()和GetIV()方法获取随机生成的密钥和IV。 2. **创建加密和解密流**:C#提供了CryptoStream类,它可以与任何其他流(如FileStream)一起使用...

    只要单片机具有真正唯一ID,就可以让加密坚不可摧

    然后,编程器和单片机之间会通过一个自定义的函数GET_IDX()来读取这个存储的IDX值,最终通过F1(ID)函数来生成最终的加密值。这一过程听起来简单,但其复杂度在于F1函数的变换逻辑需要精心设计,以确保加密的安全性。...

    sqlite3嵌入式数据库加密

    1. 安装SQLCipher库:通常通过编译源代码或者使用包管理器(如apt-get或brew)来安装。 2. 配置Qt项目:在.pro文件中添加SQLCipher库的路径,并启用相应的编译标志。 ```pro QT += sql INCLUDEPATH += /path/to...

    java 字符串加密解密

    在Java中,`java.util.Base64`类提供了便捷的BASE64编码和解码功能,如`Base64.getEncoder().encodeToString()`和`Base64.getDecoder().decode()`。 接着,MD5(Message-Digest Algorithm 5)是一种哈希函数,它...

    PHP RSA分段加密解密

    在PHP中,我们可以使用内置的`openssl_pkey_get_private()`和`openssl_pkey_get_public()`函数获取私钥和公钥,然后利用`openssl_private_encrypt()`和`openssl_public_decrypt()`进行加密和解密操作。需要注意的是...

    加密解密的原理 加密解密的原理

    - 首先,通过`Convert.FromBase64String()`方法将输入的Base64编码字符串`Get_String`解码为原始的字节数组`UnSecret_Byte`; - 然后,使用`UTF8Encoding.UTF8.GetString()`方法将字节数组转换回原始的明文字符串`...

    Base64批量加密工具

    使用`getEncoder()`和`getDecoder()`静态方法可以获取对应的实例。 2. **编码过程**:对于一个字节数组,`encodeBytes()`或`encode()`方法可以将其转换为Base64字符串。批量加密时,可以通过循环遍历文件或数据,...

    java 文字加密实例

    String base64Encoded = Base64.getEncoder().encodeToString(encrypted); System.out.println("Encrypted: " + base64Encoded); // 解密 cipher.init(Cipher.DECRYPT_MODE, secretKey); byte[] decrypted = ...

    C#数据加密简介

    在C#编程中,数据加密是一项至关重要的技术,主要用于保护敏感信息的安全,防止未经授权的访问或篡改。本文将深入探讨C#中的数据加密基础知识,包括加密算法、加密模式、密钥管理和实际应用示例。 一、加密算法 1....

    GET请求https,post请求https

    综上所述,GET和POST请求在HTTPS环境下的主要差异在于数据的提交方式和用途,而两者都得益于HTTPS提供的加密保护,提高了网络通信的安全性。在设计和实现Web服务时,应根据具体需求选择合适的请求方法,同时充分利用...

Global site tag (gtag.js) - Google Analytics