All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.github.joekerouac.common.tools.crypto.impl.AbstractHmac Maven / Gradle / Ivy

The newest version!
/*
 * Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE
 * file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file
 * to You under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the
 * License. You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
 * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
 * specific language governing permissions and limitations under the License.
 */
package com.github.joekerouac.common.tools.crypto.impl;

import java.util.Arrays;

import com.github.joekerouac.common.tools.crypto.DigestSpi;
import com.github.joekerouac.common.tools.crypto.HmacSpi;

/**
 * 抽象Hmac算法,不同hmac的差异实际上就是摘要算法的差异,所以可以对其公共算法进行统一封装
 *
 * 

* 一次初始化可以多次使用 *

* * @since 1.0.0 * @author JoeKerouac */ public abstract class AbstractHmac implements HmacSpi { /** * 块长度 */ private final int blockLen; /** * hash算法结果长度,例如SHA-256,长度就是32(256/8=32,其中256单位是bit,不是byte) */ private final int hashSize; /** * 初始化标志,true表示已经初始化 */ private boolean init; /** * 摘要算法实现 */ private DigestSpi digestSpi; /** * 当前是否是第一次更新 */ private boolean first; /** * 对应算法中的K XOR ipad */ private byte[] ipad; /** * 对应算法中的K XOR opad */ private byte[] opad; protected AbstractHmac(DigestSpi digestSpi, int hashSize, int blockLen) { this.digestSpi = digestSpi; this.first = true; this.hashSize = hashSize; this.blockLen = blockLen; this.ipad = new byte[blockLen]; this.opad = new byte[blockLen]; } @Override public void init(byte[] key) { reset(); if (key == null) { throw new IllegalArgumentException("key 不能为空"); } byte[] keyClone = key.clone(); // 对key生成摘要 if (keyClone.length > this.blockLen) { byte[] digest = this.digestSpi.digest(keyClone); // 尽快将内存中的key清空,防止密钥泄漏 Arrays.fill(keyClone, (byte)0); keyClone = digest; } // 根据rfc2104生成k_ipad和k_opad for (int i = 0; i < this.blockLen; ++i) { byte k = i < keyClone.length ? keyClone[i] : 0; this.ipad[i] = (byte)(k ^ 0x36); this.opad[i] = (byte)(k ^ 0x5C); } // 将内存中的数据尽快清空 Arrays.fill(keyClone, (byte)0); this.init = true; } @Override public void update(byte[] data, int offset, int len) { if (!init) { throw new IllegalStateException("HMAC未初始化,请先初始化"); } if (this.first) { this.digestSpi.update(this.ipad); this.first = false; } this.digestSpi.update(data, offset, len); } @Override public byte[] doFinal() { if (!init) { throw new IllegalStateException("HMAC未初始化,请先初始化"); } if (this.first) { this.digestSpi.update(this.ipad); } else { this.first = true; } byte[] result = this.digestSpi.digest(); this.digestSpi.update(this.opad); this.digestSpi.update(result); this.digestSpi.digest(result, 0); return result; } @Override public void reset() { if (!this.first) { this.digestSpi.reset(); this.first = true; } } @Override public String name() { return "Hmac" + hashAlgorithm(); } @Override public String hashAlgorithm() { return digestSpi.name(); } @Override public AbstractHmac copy() throws CloneNotSupportedException { AbstractHmac hmac = (AbstractHmac)super.clone(); hmac.digestSpi = this.digestSpi.copy(); hmac.init = this.init; hmac.ipad = this.ipad.clone(); hmac.opad = this.opad.clone(); return hmac; } @Override public int macSize() { return hashSize; } @Override public int blockLen() { return blockLen; } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy