Solo  当前访客:0 开始使用

blog,blog,blog

blog,blog,blog
浏览数: 105490    文章总数: 90   

springboot利用注解进行id加密json反序列化

1.ID加密工具类

@Slf4j
@Component
public class CryptUtil {

    @Autowired
    private CryptConfig cryptConfig;
    private static CryptConfig config;
    private static final String charset = "utf-8";


    @PostConstruct
    public void init() {
        config = cryptConfig;
    }

    /**
     * @param content 密文
     * @return 原文
     * @throws Exception
     */
    public static String decrypt(String content) {
        if (StringUtils.isEmpty(content)) {
            return "";
        }
        try {
            //反序列化AES密钥
            SecretKeySpec keySpec = new SecretKeySpec(Base64.decodeBase64(config.getKey().getBytes()), "AES");

            //128bit全零的IV向量
            byte[] iv = new byte[16];
            for (int i = 0; i < iv.length; i++) {
                iv[i] = 0;
            }
            IvParameterSpec ivParameterSpec = new IvParameterSpec(iv);

            //初始化加密器并加密
            Cipher deCipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
            deCipher.init(Cipher.DECRYPT_MODE, keySpec, ivParameterSpec);
            Codec codec = Codec.forName("Base16");
            byte[] encryptedBytes = codec.newDecoder().decode(content.getBytes());
            byte[] bytes = deCipher.doFinal(encryptedBytes);
            return new String(bytes);
        } catch (Exception e) {
            log.error("decrypt exception: {}", e);
            return "";
        }


    }

    /**
     * @param content 原文
     * @return 原文
     * @throws Exception
     */
    public static String encrypt(String content) {
        if (StringUtils.isEmpty(content)) {
            return "";
        }
        try {
            String fullAlg = "AES/CBC/PKCS5Padding";
            Cipher cipher = Cipher.getInstance(fullAlg);
            IvParameterSpec iv = new IvParameterSpec(initIv(fullAlg));
            cipher.init(
                    Cipher.ENCRYPT_MODE, new SecretKeySpec(Base64.decodeBase64(config.getKey().getBytes()), "AES"), iv);

            byte[] encryptBytes = cipher.doFinal(content.getBytes(charset));
            Codec codec = Codec.forName("Base16");
            byte[] toEncoded = codec.newEncoder().encode(encryptBytes);

            return new String(toEncoded);
        } catch (Exception e) {
            log.warn("encrypt exception:{}", e);
            return "";
        }

    }

    /**
     * 初始向量的方法, 全部为0. 这里的写法适合于其它算法,针对AES算法的话,IV值一定是128位的(16字节).
     *
     * @param fullAlg
     * @return
     * @throws GeneralSecurityException
     */
    private static byte[] initIv(String fullAlg) throws GeneralSecurityException {
        Cipher cipher = Cipher.getInstance(fullAlg);
        int blockSize = cipher.getBlockSize();
        byte[] iv = new byte[blockSize];
        for (int i = 0; i < blockSize; ++i) {
            iv[i] = 0;
        }
        return iv;
    }


}

2.反序列处理类

public class CryptDeserializer extends JsonDeserializer<Object> {

  @Override
  public Object deserialize(JsonParser p, DeserializationContext ctxt)
      throws IOException, JsonProcessingException {
   String value= p.readValueAs(String.class);
  return   CryptUtil.decrypt(value);


  }
}

3.序列化处理类

public class CryptSerializer extends JsonSerializer<Object> implements ContextualSerializer {

  private String name;

  @Override
  public void serialize(Object value, JsonGenerator gen, SerializerProvider serializers)
      throws IOException {
    String v = CryptUtil.encrypt(value.toString());
    gen.writeString(v);

  }

  @Override
  public JsonSerializer<?> createContextual(SerializerProvider prov, BeanProperty property)
      throws JsonMappingException {
    Crypt crypt = property.getAnnotation(Crypt.class);
    this.name = crypt.value();

    return this;
  }
}

4.注解类

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
@JacksonAnnotationsInside
@JsonDeserialize(using = CryptDeserializer.class)
@JsonSerialize(using = CryptSerializer.class)
public @interface Crypt  {
  String value() default "";
}

5.使用方式

public class CompanyInfoVO {

  @Crypt
  private String unitNo;
  ...