Spring Cloud Gateway+Spring Security OAuth2+JWT(一)

爱被打了一巴掌 2024-04-19 10:54 140阅读 0赞

Spring Cloud Gateway+Spring Security OAuth2+JWT(一)

  • 前言
  • 授权服务 OAuth2+JWT
    • pom
    • 授权服务器配置
    • 自定义用户
    • jwt

前言

捣鼓了一段时间的Spring cloud,想把公司的的基于用户和权限体系的基础框架也融入到Spring cloud中。查阅了一些相关资料,打算采用Spring Cloud Gateway+Spring Security OAuth2+JWT的方式。基础版本的已经搭好了,也总结一下这几天的成果。

授权服务 OAuth2+JWT

首先说明一下Spring Security OAuth2的交互数据可以有3种方式。

  1. 第一钟是基于配置的即内存
  2. 第二钟是基于内置数据结构的数据库(Spring Security OAuth2 自己定义了很多表结构和封装好的DAO 我们只要按照它给的表结构创建表就可以用了)
  3. 第三种就是我们自己定义的表

我有用了2和3,很多资料都是第一种,自己也研究了半天。不多说直接上代码

pom

如果采用redis存储token的话 要注意一下

  1. <dependency>
  2. <groupId>org.springframework.cloud</groupId>
  3. <artifactId>spring-cloud-starter-security</artifactId>
  4. </dependency>
  5. <dependency>
  6. <groupId>io.jsonwebtoken</groupId>
  7. <artifactId>jjwt</artifactId>
  8. </dependency>
  9. <dependency>
  10. <groupId>org.springframework.security.oauth</groupId>
  11. <artifactId>spring-security-oauth2</artifactId>
  12. <!-- 指明版本,解决redis存储出现的问题:java.lang.NoSuchMethodError: org.springframework.data.redis.connection.RedisConnection.set([B[B)V问题 -->
  13. <version>2.3.3.RELEASE</version>
  14. </dependency>

授权服务器配置

这里主要是配置了用户的相关信息,由于我有自己的用户表所以我就采用了实现UserService接口的一个实现类。

  1. package com.ljl.auth.config;
  2. import com.ljl.auth.service.impl.UserServiceImpl;
  3. import org.springframework.beans.factory.annotation.Autowired;
  4. import org.springframework.context.annotation.Bean;
  5. import org.springframework.context.annotation.Configuration;
  6. import org.springframework.http.HttpMethod;
  7. import org.springframework.security.authentication.AuthenticationManager;
  8. import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
  9. import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
  10. import org.springframework.security.config.annotation.web.builders.HttpSecurity;
  11. import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
  12. import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
  13. import org.springframework.security.core.userdetails.UserDetailsService;
  14. import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
  15. import org.springframework.security.crypto.password.PasswordEncoder;
  16. import javax.sql.DataSource;
  17. /** * Created by Administrator on 2019/9/3 0003. * 安全配置 */
  18. @Configuration
  19. @EnableWebSecurity
  20. @EnableGlobalMethodSecurity(prePostEnabled = true)
  21. public class SecurityConfig extends WebSecurityConfigurerAdapter {
  22. @Autowired
  23. private UserServiceImpl userService;
  24. @Autowired
  25. private DataSource dataSource;
  26. /** * 注入用户信息服务 * @return 用户信息服务对象 */
  27. @Bean
  28. public UserDetailsService userDetailsService() {
  29. return userService;
  30. }
  31. /** * 全局用户信息 * @param auth 认证管理 * @throws Exception 用户认证异常信息 */
  32. @Autowired
  33. public void globalUserDetails(AuthenticationManagerBuilder auth) throws Exception {
  34. //auth.jdbcAuthentication().dataSource(dataSource).passwordEncoder(passwordEncoder());
  35. auth.userDetailsService(userDetailsService()).passwordEncoder(passwordEncoder());
  36. }
  37. /** * 认证管理 * @return 认证管理对象 * @throws Exception 认证异常信息 */
  38. @Override
  39. @Bean
  40. public AuthenticationManager authenticationManagerBean() throws Exception {
  41. return super.authenticationManagerBean();
  42. }
  43. /** * http安全配置 * @param http http安全对象 * @throws Exception http安全异常信息 */
  44. @Override
  45. protected void configure(HttpSecurity http) throws Exception {
  46. http.authorizeRequests().antMatchers(HttpMethod.OPTIONS).permitAll().anyRequest().authenticated().and()
  47. .httpBasic().and().csrf().disable();
  48. }
  49. @Bean
  50. public PasswordEncoder passwordEncoder() {
  51. return new BCryptPasswordEncoder();
  52. }
  53. }

授权服务器配置。这边主要是token和配置客户端详情信息。
由于我用了jwt所以就不需要将token存储下来了,所以只用了OAUTH_CLIENT_DETAILS这个表。
OAuth2集成了很多表,可以去查询相关资料。

jwt我采用的是RSA加密的方法,工具类我也贴出来了。

  1. package com.ljl.auth.config;
  2. import com.ljl.common.util.RSAUtil;
  3. import org.springframework.beans.factory.annotation.Autowired;
  4. import org.springframework.context.annotation.Bean;
  5. import org.springframework.context.annotation.Configuration;
  6. import org.springframework.data.redis.connection.RedisConnectionFactory;
  7. import org.springframework.data.redis.connection.jedis.JedisConnectionFactory;
  8. import org.springframework.security.authentication.AuthenticationManager;
  9. import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
  10. import org.springframework.security.crypto.password.PasswordEncoder;
  11. import org.springframework.security.oauth2.config.annotation.configurers.ClientDetailsServiceConfigurer;
  12. import org.springframework.security.oauth2.config.annotation.web.configuration.AuthorizationServerConfigurerAdapter;
  13. import org.springframework.security.oauth2.config.annotation.web.configuration.EnableAuthorizationServer;
  14. import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerEndpointsConfigurer;
  15. import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerSecurityConfigurer;
  16. import org.springframework.security.oauth2.provider.token.TokenStore;
  17. import org.springframework.security.oauth2.provider.token.store.JwtAccessTokenConverter;
  18. import org.springframework.security.oauth2.provider.token.store.JwtTokenStore;
  19. import org.springframework.security.oauth2.provider.token.store.redis.RedisTokenStore;
  20. import javax.sql.DataSource;
  21. /** * Created by Administrator on 2019/9/3 0003. * 授权服务器配置 */
  22. @Configuration
  23. @EnableAuthorizationServer
  24. public class AuthorizationServerConfig extends AuthorizationServerConfigurerAdapter {
  25. // 认证管理器
  26. @Autowired
  27. private AuthenticationManager authenticationManager;
  28. // redis连接工厂
  29. /*@Autowired private JedisConnectionFactory JedisConnectionFactory;*/
  30. @Autowired
  31. private PasswordEncoder passwordEncoder;
  32. @Autowired
  33. private DataSource dataSource;
  34. /** * 令牌存储 * @return redis令牌存储对象 */
  35. /*@Bean public TokenStore tokenStore() { return new RedisTokenStore(JedisConnectionFactory); } @Override public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception { endpoints.authenticationManager(this.authenticationManager); endpoints.tokenStore(tokenStore()); }*/
  36. @Bean
  37. protected JwtAccessTokenConverter jwtAccessTokenConverter() {
  38. JwtAccessTokenConverter converter = new MyJwtAccessTokenConverter();
  39. converter.setKeyPair(RSAUtil.GetKeyPair());
  40. return converter;
  41. }
  42. @Bean
  43. public TokenStore jwtTokenStore() {
  44. return new JwtTokenStore(jwtAccessTokenConverter());
  45. }
  46. @Override
  47. public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
  48. endpoints.tokenStore(jwtTokenStore()).accessTokenConverter(jwtAccessTokenConverter()).authenticationManager(this.authenticationManager);
  49. }
  50. /** * OAuth 授权端点开放 */
  51. @Override
  52. public void configure(AuthorizationServerSecurityConfigurer security) throws Exception {
  53. security
  54. // 开启/oauth/token_key验证端口无权限访问
  55. .tokenKeyAccess("permitAll()")
  56. // 开启/oauth/check_token验证端口认证权限访问
  57. .checkTokenAccess("isAuthenticated()")
  58. //主要是让/oauth/token支持client_id以及client_secret作登录认证
  59. .allowFormAuthenticationForClients();
  60. }
  61. /** * OAuth 配置客户端详情信息 */
  62. @Override
  63. public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
  64. clients.jdbc(dataSource).passwordEncoder(passwordEncoder);
  65. }
  66. }

我用的是oracle

  1. -- Create table
  2. create table OAUTH_CLIENT_DETAILS
  3. (
  4. client_id VARCHAR2(255) not null,
  5. resource_ids VARCHAR2(255),
  6. client_secret VARCHAR2(255),
  7. scope VARCHAR2(255),
  8. authorized_grant_types VARCHAR2(255),
  9. web_server_redirect_uri VARCHAR2(255),
  10. authorities VARCHAR2(255),
  11. access_token_validity NUMBER(11),
  12. refresh_token_validity NUMBER(11),
  13. additional_information VARCHAR2(255),
  14. autoapprove VARCHAR2(255)
  15. )
  16. tablespace BASE
  17. pctfree 10
  18. initrans 1
  19. maxtrans 255
  20. storage
  21. (
  22. initial 64K
  23. next 1M
  24. minextents 1
  25. maxextents unlimited
  26. );

自定义用户

自定义用户表的话主要是需要实现UserService这个接口中的loadUserByUsername方法并返回一个uesr对象。
这边的查询用户是我另一个基础服务的一个接口,就是通过用户名查询数据。

  1. package com.ljl.auth.service.impl;
  2. import com.alibaba.fastjson.JSON;
  3. import com.ljl.auth.model.*;
  4. import com.ljl.auth.service.UserService;
  5. import com.ljl.base.api.UserFeignApi;
  6. import com.ljl.common.base.Pages;
  7. import com.ljl.common.base.Result;
  8. import com.ljl.common.model.BaseOperator;
  9. import com.ljl.common.util.PasswordUtil;
  10. import com.ljl.common.util.StaticData;
  11. import com.ljl.dataSource.BaseDao;
  12. import org.springframework.beans.factory.annotation.Autowired;
  13. import org.springframework.security.core.authority.AuthorityUtils;
  14. import org.springframework.security.core.userdetails.User;
  15. import org.springframework.security.core.userdetails.UserDetails;
  16. import org.springframework.security.core.userdetails.UsernameNotFoundException;
  17. import org.springframework.stereotype.Service;
  18. import javax.servlet.http.HttpServletRequest;
  19. import javax.servlet.http.HttpSession;
  20. import java.util.*;
  21. @Service("userService")
  22. public class UserServiceImpl implements UserService {
  23. @Autowired
  24. private UserFeignApi userFeignApi;
  25. @Override
  26. public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
  27. //查询用户信息
  28. BaseOperator userinfo = userFeignApi.getUserByUsername(username);
  29. //需要构造org.springframework.security.core.userdetails.User 对象包含账号密码还有用户的角色
  30. if (userinfo!=null){
  31. User user = new User(userinfo.getLoginname(),userinfo.getPassword(), AuthorityUtils.createAuthorityList("admin"));
  32. return new OauthUser(userinfo,user);
  33. }else {
  34. throw new UsernameNotFoundException("用户["+username+"]不存在");
  35. }
  36. }
  37. }

这个是我自己定义的实现了UserDetails, CredentialsContainer这两个接口的用户对象,除了再上面要用,jwt中也要用。
这边的baseUser 是我自己的用户对象。

  1. package com.ljl.auth.model;
  2. import com.ljl.common.model.BaseOperator;
  3. import org.springframework.security.core.CredentialsContainer;
  4. import org.springframework.security.core.GrantedAuthority;
  5. import org.springframework.security.core.userdetails.User;
  6. import org.springframework.security.core.userdetails.UserDetails;
  7. import java.util.Collection;
  8. /** * Created by Administrator on 2019/9/6 0006. */
  9. public class OauthUser implements UserDetails, CredentialsContainer {
  10. private final BaseOperator baseUser;
  11. private final User user;
  12. public OauthUser(BaseOperator baseUser, User user) {
  13. this.baseUser = baseUser;
  14. this.user = user;
  15. }
  16. @Override
  17. public void eraseCredentials() {
  18. user.eraseCredentials();
  19. }
  20. @Override
  21. public Collection<? extends GrantedAuthority> getAuthorities() {
  22. return user.getAuthorities();
  23. }
  24. @Override
  25. public String getPassword() {
  26. return user.getPassword();
  27. }
  28. @Override
  29. public String getUsername() {
  30. return user.getUsername();
  31. }
  32. @Override
  33. public boolean isAccountNonExpired() {
  34. return user.isAccountNonExpired();
  35. }
  36. @Override
  37. public boolean isAccountNonLocked() {
  38. return user.isAccountNonLocked();
  39. }
  40. @Override
  41. public boolean isCredentialsNonExpired() {
  42. return user.isCredentialsNonExpired();
  43. }
  44. @Override
  45. public boolean isEnabled() {
  46. return user.isEnabled();
  47. }
  48. public BaseOperator getBaseOperator() {
  49. return baseUser;
  50. }
  51. }

jwt

jwt生成token 我们可以自己定义jwt里面的内容

  1. package com.ljl.auth.config;
  2. import com.ljl.auth.model.OauthUser;
  3. import org.springframework.security.oauth2.common.DefaultOAuth2AccessToken;
  4. import org.springframework.security.oauth2.common.OAuth2AccessToken;
  5. import org.springframework.security.oauth2.provider.OAuth2Authentication;
  6. import org.springframework.security.oauth2.provider.token.store.JwtAccessTokenConverter;
  7. import java.util.HashMap;
  8. /** * Created by Administrator on 2019/9/6 0006. * 自定义的token */
  9. public class MyJwtAccessTokenConverter extends JwtAccessTokenConverter {
  10. @Override
  11. public OAuth2AccessToken enhance(OAuth2AccessToken accessToken, OAuth2Authentication authentication) {
  12. if (accessToken instanceof DefaultOAuth2AccessToken) {
  13. //((DefaultOAuth2AccessToken) accessToken).setRefreshToken();
  14. Object principal = authentication.getPrincipal();
  15. if (principal instanceof OauthUser) {
  16. OauthUser user = (OauthUser) principal;
  17. HashMap<String, Object> map = new HashMap<>();
  18. map.put("user_id", user.getBaseOperator().getUserid());
  19. map.put("phone", user.getBaseOperator().getTelphonenum());
  20. ((DefaultOAuth2AccessToken) accessToken).setAdditionalInformation(map);
  21. }
  22. }
  23. return super.enhance(accessToken, authentication);
  24. }
  25. }

RSA工具类

  1. package com.ljl.common.util;
  2. import org.slf4j.Logger;
  3. import org.slf4j.LoggerFactory;
  4. import org.springframework.core.io.ClassPathResource;
  5. import org.springframework.core.io.Resource;
  6. import org.springframework.util.Base64Utils;
  7. import javax.crypto.Cipher;
  8. import java.io.ByteArrayOutputStream;
  9. import java.io.FileNotFoundException;
  10. import java.io.FileOutputStream;
  11. import java.io.IOException;
  12. import java.security.*;
  13. import java.security.interfaces.RSAPrivateKey;
  14. import java.security.interfaces.RSAPublicKey;
  15. import java.security.spec.InvalidKeySpecException;
  16. import java.security.spec.PKCS8EncodedKeySpec;
  17. import java.security.spec.X509EncodedKeySpec;
  18. import java.util.Base64;
  19. import java.util.Properties;
  20. /** * 实现RSA加解密 * @author : lijialun * @description: */
  21. public class RSAUtil {
  22. private static final Logger LOGGER = LoggerFactory.getLogger(RSAUtil.class);
  23. /** 算法名称 */
  24. private static final String ALGORITHM = "RSA";
  25. /** RSA签名算法 */
  26. private static final String RSA_SIGNATURE_ALGORITHM = "SHA256WithRSA";
  27. /** 默认密钥大小 */
  28. private static final int KEY_SIZE = 2048;
  29. /** 最大解密长度 */
  30. private static final int MAX_DECRYPT_BLOCK = 256;
  31. /** 用来指定保存密钥对的文件名和存储的名称 */
  32. private static final String PUBLIC_KEY_NAME = "publicKey";
  33. private static final String PRIVATE_KEY_NAME = "privateKey";
  34. private static final String PUBLIC_FILENAME = "publicKey.properties";
  35. private static final String PRIVATE_FILENAME = "privateKey.properties";
  36. private static Properties pubProperties;
  37. private static Properties PriProperties;
  38. /** 密钥对生成器 */
  39. private static KeyPairGenerator keyPairGenerator = null;
  40. private static KeyFactory keyFactory = null;
  41. /** 缓存的密钥对 */
  42. private static KeyPair keyPair = null;
  43. /** Base64 编码/解码器 JDK1.8 */
  44. private static Base64.Decoder decoder = Base64.getDecoder();
  45. private static Base64.Encoder encoder = Base64.getEncoder();
  46. /** 初始化密钥工厂 */
  47. static{
  48. try {
  49. keyPairGenerator = KeyPairGenerator.getInstance(ALGORITHM);
  50. keyFactory = KeyFactory.getInstance(ALGORITHM);
  51. //generateKeyPair();
  52. getInstanceForPub();
  53. getInstanceForPri();
  54. } catch (NoSuchAlgorithmException e) {
  55. LOGGER.error(e.getMessage(),e);
  56. }
  57. }
  58. /*初始化公钥config*/
  59. private static Properties getInstanceForPub(){
  60. if (pubProperties == null) {
  61. Resource res =new ClassPathResource(PUBLIC_FILENAME);
  62. pubProperties = new Properties();
  63. try {
  64. pubProperties.load(res.getInputStream());
  65. } catch (IOException e) {
  66. e.printStackTrace();
  67. }
  68. }
  69. return pubProperties;
  70. }
  71. /*初始钥私钥config*/
  72. private static Properties getInstanceForPri(){
  73. if (PriProperties == null) {
  74. Resource res =new ClassPathResource(PRIVATE_FILENAME);
  75. PriProperties = new Properties();
  76. try {
  77. PriProperties.load(res.getInputStream());
  78. } catch (IOException e) {
  79. e.printStackTrace();
  80. }
  81. }
  82. return PriProperties;
  83. }
  84. /** 私有构造器 */
  85. private RSAUtil(){ }
  86. /** * 生成密钥对 * 将密钥分别用Base64编码保存到#publicKey.properties#和#privateKey.properties#文件中 * 保存的默认名称分别为publicKey和privateKey * * */
  87. public static synchronized void generateKeyPair(){
  88. try {
  89. keyPairGenerator.initialize(KEY_SIZE,new SecureRandom());
  90. keyPair = keyPairGenerator.generateKeyPair();
  91. } catch (InvalidParameterException e){
  92. LOGGER.error("KeyPairGenerator does not support a key length of " + KEY_SIZE + ".",e);
  93. } catch (NullPointerException e){
  94. LOGGER.error("RSAUtils#key_pair_gen is null,can not generate KeyPairGenerator instance.",e);
  95. }
  96. RSAPublicKey rsaPublicKey = (RSAPublicKey)keyPair.getPublic();
  97. RSAPrivateKey rsaPrivateKey = (RSAPrivateKey)keyPair.getPrivate();
  98. String publicKeyString = encoder.encodeToString(rsaPublicKey.getEncoded());
  99. String privateKeyString = encoder.encodeToString(rsaPrivateKey.getEncoded());
  100. System.out.println("公钥:"+publicKeyString);
  101. System.out.println("私钥:"+privateKeyString);
  102. storeKey(publicKeyString,PUBLIC_KEY_NAME,pubProperties,PUBLIC_FILENAME);
  103. storeKey(privateKeyString,PRIVATE_KEY_NAME,PriProperties,PRIVATE_FILENAME);
  104. }
  105. /** * 将指定的密钥字符串保存到文件中,如果找不到文件,就创建 * @param keyString 密钥的Base64编码字符串(值) * @param keyName 保存在文件中的名称(键) * @param properties 目标文件 */
  106. private static void storeKey(String keyString,String keyName,Properties properties,String fileName){
  107. try {
  108. Resource res =new ClassPathResource(fileName);
  109. FileOutputStream oFile = new FileOutputStream(res.getFile(), false);
  110. properties.setProperty(keyName,keyString);
  111. properties.store(oFile, keyName);
  112. oFile.close();
  113. } catch (FileNotFoundException e) {
  114. e.printStackTrace();
  115. } catch (IOException e) {
  116. e.printStackTrace();
  117. }
  118. }
  119. /** * 获取密钥字符串 * @param keyName 需要获取的密钥名 * @param properties 密钥文件 * @return Base64编码的密钥字符串 */
  120. private static String getKeyString(String keyName,Properties properties){
  121. return properties.getProperty(keyName);
  122. }
  123. /** * 从文件获取RSA公钥 * @return RSA公钥 * @throws InvalidKeySpecException */
  124. public static RSAPublicKey getPublicKey(){
  125. try {
  126. byte[] keyBytes = decoder.decode(getKeyString(PUBLIC_KEY_NAME,pubProperties));
  127. X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(keyBytes);
  128. RSAPublicKey rsa = (RSAPublicKey)keyFactory.generatePublic(x509EncodedKeySpec);
  129. return rsa;
  130. }catch (InvalidKeySpecException e) {
  131. LOGGER.error("getPublicKey()#" + e.getMessage(),e);
  132. }
  133. return null;
  134. }
  135. /** * 从文件获取RSA私钥 * @return RSA私钥 * @throws InvalidKeySpecException */
  136. public static RSAPrivateKey getPrivateKey(){
  137. try {
  138. byte[] keyBytes = decoder.decode(getKeyString(PRIVATE_KEY_NAME,PriProperties));
  139. PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(keyBytes);
  140. return (RSAPrivateKey)keyFactory.generatePrivate(pkcs8EncodedKeySpec);
  141. } catch (InvalidKeySpecException e) {
  142. LOGGER.error("getPrivateKey()#" + e.getMessage(),e);
  143. }
  144. return null;
  145. }
  146. /** * RSA公钥加密 */
  147. public static byte[] encryptByPublicKey(byte[] data) throws Exception {
  148. // 对数据加密
  149. Cipher cipher = Cipher.getInstance("RSA");
  150. cipher.init(Cipher.ENCRYPT_MODE, getPublicKey());
  151. int inputLen = data.length;
  152. ByteArrayOutputStream out = new ByteArrayOutputStream();
  153. int offSet = 0;
  154. byte[] cache;
  155. int i = 0;
  156. // 对数据分段加密
  157. while (inputLen - offSet > 0) {
  158. if (inputLen - offSet > 117) {
  159. cache = cipher.doFinal(data, offSet, 117);
  160. } else {
  161. cache = cipher.doFinal(data, offSet, inputLen - offSet);
  162. }
  163. out.write(cache, 0, cache.length);
  164. i++;
  165. offSet = i * 117;
  166. }
  167. byte[] encryptedData = out.toByteArray();
  168. out.close();
  169. return encryptedData;
  170. }
  171. //私钥解密
  172. public static byte[] decryptByPrivateKey(byte[] encryptedData) throws Exception {
  173. PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(getPrivateKey().getEncoded());
  174. KeyFactory keyFactory = KeyFactory.getInstance("RSA");
  175. Key privateK = keyFactory.generatePrivate(pkcs8KeySpec);
  176. Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
  177. cipher.init(Cipher.DECRYPT_MODE, privateK);
  178. int inputLen = encryptedData.length;
  179. ByteArrayOutputStream out = new ByteArrayOutputStream();
  180. int offSet = 0;
  181. byte[] cache;
  182. int i = 0;
  183. // 对数据分段解密
  184. while (inputLen - offSet > 0) {
  185. if (inputLen - offSet > MAX_DECRYPT_BLOCK) {
  186. cache = cipher.doFinal(encryptedData, offSet, MAX_DECRYPT_BLOCK);
  187. } else {
  188. cache = cipher.doFinal(encryptedData, offSet, inputLen - offSet);
  189. }
  190. out.write(cache, 0, cache.length);
  191. i++;
  192. offSet = i * MAX_DECRYPT_BLOCK;
  193. }
  194. byte[] decryptedData = out.toByteArray();
  195. out.close();
  196. return decryptedData;
  197. }
  198. /** * RSA公钥验签 * * @param data * 待签名字符串 * 公钥(Base64编码) * @return 验签结果 * @throws Exception */
  199. public static boolean verify(byte[] data, String sign) throws Exception {
  200. Signature signature = Signature.getInstance(RSA_SIGNATURE_ALGORITHM);
  201. signature.initVerify(getPublicKey());
  202. signature.update(data);
  203. return signature.verify(Base64Utils.decodeFromUrlSafeString(sign));
  204. }
  205. /** * RSA私钥签名:签名方式SHA1withRSA * * @param data * 待签名byte[] * 私钥(Base64编码) * @return 签名byte[] * @throws Exception */
  206. public static byte[] sign(byte[] data) throws Exception {
  207. // Sign
  208. Signature signature = Signature.getInstance(RSA_SIGNATURE_ALGORITHM);
  209. signature.initSign(getPrivateKey());
  210. signature.update(data);
  211. return signature.sign();
  212. }
  213. /** * 将char转换为byte * @param c char * @return byte */
  214. private static byte toByte(char c){
  215. return (byte)"0123456789ABCDEF".indexOf(c);
  216. }
  217. public static int getValidLength(byte[] bytes){
  218. int i = 0;
  219. if (null == bytes || 0 == bytes.length)
  220. return i ;
  221. for (; i < bytes.length; i++) {
  222. if (bytes[i] == '\0')
  223. break;
  224. }
  225. return i + 1;
  226. }
  227. public static KeyPair GetKeyPair(){
  228. return new KeyPair(getPublicKey(),getPrivateKey());
  229. }
  230. }

发表评论

表情:
评论列表 (有 0 条评论,140人围观)

还没有评论,来说两句吧...

相关阅读

    相关 Spring security Oauth2+JWT

    企业级认证授权技术 一丶用户认证与授权 > 每个项目最基本的也是最重要的是安全,用户认证与授权,是最重要的,用户认证身份。 1.1什么是用户身份认证? > 用户身份