临时存储
This commit is contained in:
14
build.gradle
14
build.gradle
@@ -15,8 +15,8 @@ sourceSets {
|
|||||||
/** 统一编译编码 */
|
/** 统一编译编码 */
|
||||||
tasks.withType(JavaCompile).configureEach { t ->
|
tasks.withType(JavaCompile).configureEach { t ->
|
||||||
t.options.encoding = "UTF-8"
|
t.options.encoding = "UTF-8"
|
||||||
t.sourceCompatibility = "1.5"
|
t.sourceCompatibility = "1.8"
|
||||||
t.targetCompatibility = "1.5"
|
t.targetCompatibility = "1.8"
|
||||||
def jcHome = System.getenv("JC_HOME")
|
def jcHome = System.getenv("JC_HOME")
|
||||||
if (!jcHome) throw new GradleException("缺少 JC_HOME")
|
if (!jcHome) throw new GradleException("缺少 JC_HOME")
|
||||||
t.options.bootstrapClasspath = files("${jcHome}/lib/api_classic.jar")
|
t.options.bootstrapClasspath = files("${jcHome}/lib/api_classic.jar")
|
||||||
@@ -34,10 +34,12 @@ dependencies {
|
|||||||
|
|
||||||
/** ===== 用本地 JCDK converter 生成 CAP ===== */
|
/** ===== 用本地 JCDK converter 生成 CAP ===== */
|
||||||
def pkgName = "com.zuc.zuc256" // ← 改成你的包名
|
def pkgName = "com.zuc.zuc256" // ← 改成你的包名
|
||||||
def appletClass = "${pkgName}.MyApplet" // ← 改成你的 Applet 全类名
|
def appletClass = "${pkgName}.XwSecurity" // ← 改成你的 Applet 全类名
|
||||||
def packageAID = "0xA0:0x00:0x00:0x03:0x33:0x01:0x01" // ← 改成你的包 AID
|
def packageAID = "0xA0:0x00:0x00:0x03:0x33:0x01:0x01" // ← 改成你的包 AID
|
||||||
def appletAID = "0xA0:0x00:0x00:0x03:0x33:0x01:0x01:0x01"// ← 改成你的实例 AID
|
def appletAID = "0xA0:0x00:0x00:0x03:0x33:0x01:0x01:0x01"// ← 改成你的实例 AID
|
||||||
def ver = "1.0"
|
def ver = "1.0"
|
||||||
|
|
||||||
|
|
||||||
tasks.register("buildCap") {
|
tasks.register("buildCap") {
|
||||||
group = "build"
|
group = "build"
|
||||||
description = "Generate CAP via JCDK converter.bat"
|
description = "Generate CAP via JCDK converter.bat"
|
||||||
@@ -61,7 +63,7 @@ tasks.register("buildCap") {
|
|||||||
if (!batFile.exists()) throw new GradleException("未找到 converter.bat:${batFile}")
|
if (!batFile.exists()) throw new GradleException("未找到 converter.bat:${batFile}")
|
||||||
|
|
||||||
// 确认 .class 存在
|
// 确认 .class 存在
|
||||||
def cls = file("$buildDir/classes/java/main/${pkgName.replace('.','/')}/MyApplet.class")
|
def cls = file("$buildDir/classes/java/main/${pkgName.replace('.','/')}/XwSecurity.class")
|
||||||
if (!cls.exists()) throw new GradleException("未找到已编译类:${cls}")
|
if (!cls.exists()) throw new GradleException("未找到已编译类:${cls}")
|
||||||
|
|
||||||
|
|
||||||
@@ -96,7 +98,7 @@ tasks.register("buildCap") {
|
|||||||
|
|
||||||
if (result.exitValue != 0) {
|
if (result.exitValue != 0) {
|
||||||
println "---- converter.log tail ----"
|
println "---- converter.log tail ----"
|
||||||
println logFile.readLines("GBK").takeRight(80).join(System.lineSeparator())
|
println logFile.readLines("UTF-8").takeRight(80).join(System.lineSeparator())
|
||||||
throw new GradleException("converter 退出码:${result.exitValue}")
|
throw new GradleException("converter 退出码:${result.exitValue}")
|
||||||
} else {
|
} else {
|
||||||
println "CAP 生成成功,目录:${file("$buildDir/javacard").absolutePath}"
|
println "CAP 生成成功,目录:${file("$buildDir/javacard").absolutePath}"
|
||||||
@@ -104,3 +106,5 @@ tasks.register("buildCap") {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
3
gradle.properties
Normal file
3
gradle.properties
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
# 统一 Gradle/JVM 的默认编码
|
||||||
|
org.gradle.jvmargs=-Xmx2g -Dfile.encoding=UTF-8
|
||||||
|
systemProp.file.encoding=UTF-8
|
||||||
4
gradle/wrapper/gradle-wrapper.properties
vendored
4
gradle/wrapper/gradle-wrapper.properties
vendored
@@ -2,6 +2,4 @@ distributionBase=GRADLE_USER_HOME
|
|||||||
distributionPath=wrapper/dists
|
distributionPath=wrapper/dists
|
||||||
distributionUrl=https\://services.gradle.org/distributions/gradle-6.9.4-bin.zip
|
distributionUrl=https\://services.gradle.org/distributions/gradle-6.9.4-bin.zip
|
||||||
zipStoreBase=GRADLE_USER_HOME
|
zipStoreBase=GRADLE_USER_HOME
|
||||||
zipStorePath=wrapper/dists
|
zipStorePath=wrapper/dists
|
||||||
org.gradle.jvmargs=-Dfile.encoding=UTF-8
|
|
||||||
org.gradle.console=plain
|
|
||||||
19
src/com/zuc/zuc256/Method.java
Normal file
19
src/com/zuc/zuc256/Method.java
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
package com.zuc.zuc256;
|
||||||
|
|
||||||
|
import javacard.framework.APDU;
|
||||||
|
|
||||||
|
public class Method {
|
||||||
|
|
||||||
|
public void processData(APDU apdu)
|
||||||
|
{
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public void updateKey(APDU apdu)
|
||||||
|
{
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -1,29 +0,0 @@
|
|||||||
package com.zuc.zuc256;
|
|
||||||
|
|
||||||
import javacard.framework.*;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 最小 JavaCard Applet 示例
|
|
||||||
*/
|
|
||||||
public class MyApplet extends Applet {
|
|
||||||
|
|
||||||
// 构造函数:一般初始化状态
|
|
||||||
protected MyApplet() {
|
|
||||||
register(); // 必须调用,完成注册
|
|
||||||
}
|
|
||||||
|
|
||||||
// 安装方法:CAP 文件安装时调用
|
|
||||||
public static void install(byte[] bArray, short bOffset, byte bLength) {
|
|
||||||
new MyApplet();
|
|
||||||
}
|
|
||||||
|
|
||||||
// 处理 APDU 命令
|
|
||||||
@Override
|
|
||||||
public void process(APDU apdu) throws ISOException {
|
|
||||||
if (selectingApplet()) {
|
|
||||||
return; // 选择时无需处理数据
|
|
||||||
}
|
|
||||||
// 默认:所有指令不支持
|
|
||||||
ISOException.throwIt(ISO7816.SW_INS_NOT_SUPPORTED);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
81
src/com/zuc/zuc256/XwSecurity.java
Normal file
81
src/com/zuc/zuc256/XwSecurity.java
Normal file
@@ -0,0 +1,81 @@
|
|||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
package com.zuc.zuc256;
|
||||||
|
|
||||||
|
|
||||||
|
import javacard.framework.Applet;
|
||||||
|
import javacard.framework.ISOException;
|
||||||
|
import javacard.framework.ISO7816;
|
||||||
|
import javacard.framework.APDU;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author liuww
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class XwSecurity extends Applet {
|
||||||
|
|
||||||
|
public static final byte INS_PROCESS_DATA = (byte)0xCA;
|
||||||
|
|
||||||
|
public static final byte INS_STORE_DATA = (byte)0xE2;
|
||||||
|
|
||||||
|
public static final byte INS_INITIAL_UPDATE = (byte)0x50;
|
||||||
|
|
||||||
|
public static final byte INS_EXTERNAL_AUTH = (byte)0x82;
|
||||||
|
|
||||||
|
private Method method;
|
||||||
|
|
||||||
|
public XwSecurity(byte[] bArray, short bOffset, byte bLength) {
|
||||||
|
// TODO Auto-generated constructor stub
|
||||||
|
method = new Method();
|
||||||
|
|
||||||
|
register(bArray, (short)(bOffset + 1), bArray[bOffset]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void install(byte[] bArray, short bOffset, byte bLength)
|
||||||
|
{
|
||||||
|
// GP-compliant JavaCard applet registration
|
||||||
|
new XwSecurity(bArray, bOffset, bLength);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void process(APDU apdu)
|
||||||
|
{
|
||||||
|
// Good practice: Return 9000 on SELECT
|
||||||
|
if(selectingApplet())
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(method == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
byte[] buf = apdu.getBuffer();
|
||||||
|
switch (buf[ISO7816.OFFSET_INS])
|
||||||
|
{
|
||||||
|
case INS_INITIAL_UPDATE:
|
||||||
|
// SecureChannel sc = GPSystem.getSecureChannel();
|
||||||
|
// sc.processSecurity(apdu);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case INS_EXTERNAL_AUTH:
|
||||||
|
// sc = GPSystem.getSecureChannel();
|
||||||
|
// sc.processSecurity(apdu);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case INS_PROCESS_DATA:
|
||||||
|
method.processData(apdu);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case INS_STORE_DATA:
|
||||||
|
method.updateKey(apdu);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
// good practice: If you don't know the INStruction, say so:
|
||||||
|
ISOException.throwIt(ISO7816.SW_INS_NOT_SUPPORTED);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -63,7 +63,10 @@ public final class Zuc256Core {
|
|||||||
a = (a & 0x7FFFFFFF) + (a >>> 31);
|
a = (a & 0x7FFFFFFF) + (a >>> 31);
|
||||||
int v = (int) ((a & 0x7FFFFFFF) + (a >>> 31));
|
int v = (int) ((a & 0x7FFFFFFF) + (a >>> 31));
|
||||||
|
|
||||||
System.arraycopy(LFSR, 1, LFSR, 0, 15);
|
// System.arraycopy(LFSR, 1, LFSR, 0, 15);
|
||||||
|
for (short i = 0; i < 15; i++) {
|
||||||
|
LFSR[i] = LFSR[i + 1];
|
||||||
|
}
|
||||||
LFSR[15] = v;
|
LFSR[15] = v;
|
||||||
|
|
||||||
state.R1 = R1;
|
state.R1 = R1;
|
||||||
@@ -119,7 +122,10 @@ public final class Zuc256Core {
|
|||||||
a = (a & 0x7FFFFFFF) + (a >>> 31);
|
a = (a & 0x7FFFFFFF) + (a >>> 31);
|
||||||
int v = (int) ((a & 0x7FFFFFFF) + (a >>> 31));
|
int v = (int) ((a & 0x7FFFFFFF) + (a >>> 31));
|
||||||
|
|
||||||
System.arraycopy(LFSR, 1, LFSR, 0, 15);
|
// System.arraycopy(LFSR, 1, LFSR, 0, 15);
|
||||||
|
for (short j = 0; j < (short)15; j++) {
|
||||||
|
LFSR[j] = LFSR[(short)(j + 1)];
|
||||||
|
}
|
||||||
LFSR[15] = v;
|
LFSR[15] = v;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -171,7 +177,11 @@ public final class Zuc256Core {
|
|||||||
a = (a & 0x7FFFFFFF) + (a >>> 31);
|
a = (a & 0x7FFFFFFF) + (a >>> 31);
|
||||||
int v = (int) ((a & 0x7FFFFFFF) + (a >>> 31));
|
int v = (int) ((a & 0x7FFFFFFF) + (a >>> 31));
|
||||||
|
|
||||||
System.arraycopy(LFSR, 1, LFSR, 0, 15);
|
// System.arraycopy(LFSR, 1, LFSR, 0, 15);
|
||||||
|
for (short i = 0; i < (short)15; i++) {
|
||||||
|
LFSR[i] = LFSR[(short)(i + 1)];
|
||||||
|
}
|
||||||
|
|
||||||
LFSR[15] = v;
|
LFSR[15] = v;
|
||||||
|
|
||||||
state.R1 = R1;
|
state.R1 = R1;
|
||||||
@@ -250,7 +260,10 @@ public final class Zuc256Core {
|
|||||||
v = add31(v, rot31(LFSR[15], 15));
|
v = add31(v, rot31(LFSR[15], 15));
|
||||||
v = add31(v, W >>> 1);
|
v = add31(v, W >>> 1);
|
||||||
|
|
||||||
System.arraycopy(LFSR, 1, LFSR, 0, 15);
|
// System.arraycopy(LFSR, 1, LFSR, 0, 15);
|
||||||
|
for (short j = 0; j < (short)15; j++) {
|
||||||
|
LFSR[j] = LFSR[(short)(j + 1)];
|
||||||
|
}
|
||||||
LFSR[15] = v;
|
LFSR[15] = v;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -284,7 +297,10 @@ public final class Zuc256Core {
|
|||||||
a = (a & 0x7FFFFFFF) + (a >>> 31);
|
a = (a & 0x7FFFFFFF) + (a >>> 31);
|
||||||
int v = (int) ((a & 0x7FFFFFFF) + (a >>> 31));
|
int v = (int) ((a & 0x7FFFFFFF) + (a >>> 31));
|
||||||
|
|
||||||
System.arraycopy(LFSR, 1, LFSR, 0, 15);
|
// System.arraycopy(LFSR, 1, LFSR, 0, 15);
|
||||||
|
for (short i = 0; i < (short)15; i++) {
|
||||||
|
LFSR[i] = LFSR[(short)(i + 1)];
|
||||||
|
}
|
||||||
LFSR[15] = v;
|
LFSR[15] = v;
|
||||||
|
|
||||||
key.R1 = R1;
|
key.R1 = R1;
|
||||||
|
|||||||
@@ -1,9 +1,8 @@
|
|||||||
package com.zuc.zuc256;
|
package com.zuc.zuc256;
|
||||||
|
|
||||||
import java.util.Arrays;
|
|
||||||
|
|
||||||
import static com.zuc.zuc256.Zuc256Util.extractIv;
|
import static com.zuc.zuc256.Zuc256Util.extractIv;
|
||||||
import static com.zuc.zuc256.Zuc256Util.printHex;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -12,22 +11,45 @@ import static com.zuc.zuc256.Zuc256Util.printHex;
|
|||||||
*/
|
*/
|
||||||
public final class Zuc256Demo {
|
public final class Zuc256Demo {
|
||||||
|
|
||||||
public static void main(String[] args) {
|
public static void main(short args[]) {
|
||||||
// 1. 明文
|
// 1. 明文
|
||||||
byte[] plaintext = "ZUC256对称加解密测试:1234567890".getBytes();
|
byte[] plaintext = new byte[] {
|
||||||
int plaintextLen = plaintext.length;
|
0x5A, 0x55, 0x43, 0x32, 0x35, 0x36,
|
||||||
System.out.println("明文: " + new String(plaintext));
|
(byte)0xE5,(byte)0xAF,(byte)0xB9,(byte)0xE7,(byte)0xA7,(byte)0xB0,
|
||||||
printHex("明文(十六进制)", plaintext, plaintextLen);
|
(byte)0xE5,(byte)0x8A,(byte)0xA0,(byte)0xE8,(byte)0xA7,(byte)0xA3,
|
||||||
|
(byte)0xE5,(byte)0xAF,(byte)0x86,(byte)0xE6,(byte)0xB5,(byte)0x8B,
|
||||||
|
(byte)0xE8,(byte)0xAF,(byte)0x95, 0x3A,
|
||||||
|
0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x30
|
||||||
|
}; // 长度=38 ZUC256加密测试
|
||||||
|
short plaintextLen = (short)plaintext.length;
|
||||||
|
// System.out.println("明文: " + new String(plaintext));
|
||||||
|
// printHex("明文(十六进制)", plaintext, plaintextLen);
|
||||||
|
|
||||||
// 2. 密钥(32字节ASCII)
|
// 2. 密钥(32字节ASCII)
|
||||||
byte[] key = "0123456789abcdef0123456789abcdef".getBytes();
|
byte[] key = new byte[] {
|
||||||
printHex("密钥", key, 32);
|
0x30, 0x31, 0x32, 0x33, // "0123"
|
||||||
|
0x34, 0x35, 0x36, 0x37, // "4567"
|
||||||
|
0x38, 0x39, 0x61, 0x62, // "89ab"
|
||||||
|
0x63, 0x64, 0x65, 0x66, // "cdef"
|
||||||
|
0x30, 0x31, 0x32, 0x33,
|
||||||
|
0x34, 0x35, 0x36, 0x37,
|
||||||
|
0x38, 0x39, 0x61, 0x62,
|
||||||
|
0x63, 0x64, 0x65, 0x66
|
||||||
|
};
|
||||||
|
// byte[] key = "0123456789abcdef0123456789abcdef".getBytes();
|
||||||
|
// printHex("密钥", key, 32);
|
||||||
|
|
||||||
// 3. 初始向量(25字节ASCII)
|
// 3. 初始向量(25字节ASCII)
|
||||||
byte[] inputIv25Byte = "0123456789abcdefg01234567".getBytes();
|
// byte[] inputIv25Byte = "0123456789abcdefg01234567".getBytes();
|
||||||
|
byte[] inputIv25Byte = new byte[] {
|
||||||
|
0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, // "01234567"
|
||||||
|
0x38, 0x39, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, // "89abcdef"
|
||||||
|
0x67, // "g"
|
||||||
|
0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37 // "01234567"
|
||||||
|
};
|
||||||
byte[] iv = new byte[23];
|
byte[] iv = new byte[23];
|
||||||
extractIv(inputIv25Byte, iv);
|
extractIv(inputIv25Byte, iv);
|
||||||
printHex("提取后的IV", iv, 23);
|
// printHex("提取后的IV", iv, 23);
|
||||||
|
|
||||||
// 4. 分配加密/解密缓冲区
|
// 4. 分配加密/解密缓冲区
|
||||||
byte[] ciphertext = new byte[plaintextLen];
|
byte[] ciphertext = new byte[plaintextLen];
|
||||||
@@ -37,25 +59,25 @@ public final class Zuc256Demo {
|
|||||||
Zuc256State stateEnc = new Zuc256State();
|
Zuc256State stateEnc = new Zuc256State();
|
||||||
Zuc256Core.initState(stateEnc, key, iv);
|
Zuc256Core.initState(stateEnc, key, iv);
|
||||||
zuc256Crypt(stateEnc, plaintext, plaintextLen, ciphertext);
|
zuc256Crypt(stateEnc, plaintext, plaintextLen, ciphertext);
|
||||||
printHex("密文", ciphertext, plaintextLen);
|
// printHex("密文", ciphertext, plaintextLen);
|
||||||
|
|
||||||
// 6. 解密(重新初始化状态)
|
// 6. 解密(重新初始化状态)
|
||||||
Zuc256State stateDec = new Zuc256State();
|
Zuc256State stateDec = new Zuc256State();
|
||||||
Zuc256Core.initState(stateDec, key, iv);
|
Zuc256Core.initState(stateDec, key, iv);
|
||||||
zuc256Crypt(stateDec, ciphertext, plaintextLen, decryptedtext);
|
zuc256Crypt(stateDec, ciphertext, plaintextLen, decryptedtext);
|
||||||
printHex("解密后", decryptedtext, plaintextLen);
|
// printHex("解密后", decryptedtext, plaintextLen);
|
||||||
System.out.println("解密文本: " + new String(decryptedtext));
|
// System.out.println("解密文本: " + new String(decryptedtext));
|
||||||
|
|
||||||
// 7. 验证结果
|
// 7. 验证结果
|
||||||
if (Arrays.equals(plaintext, decryptedtext)) {
|
// if (Arrays.equals(plaintext, decryptedtext)) {
|
||||||
System.out.println("=== 测试成功: 解密结果与明文一致 ===");
|
// System.out.println("=== 测试成功: 解密结果与明文一致 ===");
|
||||||
} else {
|
// } else {
|
||||||
System.out.println("=== 测试失败: 解密结果与明文不一致 ===");
|
// System.out.println("=== 测试失败: 解密结果与明文不一致 ===");
|
||||||
}
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
// 一次性加密
|
// 一次性加密
|
||||||
public static void zuc256Crypt(Zuc256State state, byte[] in, int inlen, byte[] out) {
|
public static void zuc256Crypt(Zuc256State state, byte[] in, short inlen, byte[] out) {
|
||||||
if (state == null || in == null || out == null) return;
|
if (state == null || in == null || out == null) return;
|
||||||
|
|
||||||
Zuc256EncryptCtx ctx = new Zuc256EncryptCtx(state);
|
Zuc256EncryptCtx ctx = new Zuc256EncryptCtx(state);
|
||||||
@@ -68,6 +90,6 @@ public final class Zuc256Demo {
|
|||||||
System.arraycopy(out, remainingOffset, finishOut, 0, finishOut.length);
|
System.arraycopy(out, remainingOffset, finishOut, 0, finishOut.length);
|
||||||
}
|
}
|
||||||
ctx.finish(finishOut);
|
ctx.finish(finishOut);
|
||||||
System.arraycopy(finishOut, 0, out, remainingOffset, finishOut.length);
|
System.arraycopy(finishOut, (short)0, out, (short)remainingOffset, (short)finishOut.length);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
package com.zuc.zuc256;
|
package com.zuc.zuc256;
|
||||||
|
|
||||||
import java.util.Arrays;
|
import javacard.framework.Util;
|
||||||
|
|
||||||
import static com.zuc.zuc256.Zuc256Core.zuc256GenerateKeystream;
|
import static com.zuc.zuc256.Zuc256Core.zuc256GenerateKeystream;
|
||||||
import static com.zuc.zuc256.Zuc256Core.zuc256GenerateKeyword;
|
import static com.zuc.zuc256.Zuc256Core.zuc256GenerateKeyword;
|
||||||
@@ -33,27 +33,32 @@ public final class Zuc256EncryptCtx {
|
|||||||
|
|
||||||
// 初始化加密上下文
|
// 初始化加密上下文
|
||||||
public void init(byte[] key32, byte[] iv) {
|
public void init(byte[] key32, byte[] iv) {
|
||||||
Arrays.fill(this.buf, (byte) 0);
|
Util.arrayFillNonAtomic(this.buf, (short) 0, (short) this.buf.length, (byte) 0);
|
||||||
this.buflen = 0;
|
this.buflen = 0;
|
||||||
Zuc256Core.initState(this.state, key32, iv);
|
Zuc256Core.initState(this.state, key32, iv);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 分阶段处理加密数据
|
// 分阶段处理加密数据
|
||||||
public void update(byte[] in, int inlen, byte[] out) {
|
public void update(byte[] in, short inlen, byte[] out) {
|
||||||
if (in == null || out == null || inlen == 0) return;
|
if (in == null || out == null || inlen == 0) return;
|
||||||
|
|
||||||
// 处理缓冲区中剩余的非4字节数据
|
// 处理缓冲区中剩余的非4字节数据
|
||||||
if (this.buflen > 0) {
|
if (this.buflen > 0) {
|
||||||
int need = 4 - this.buflen;
|
int need = 4 - this.buflen;
|
||||||
int copy = Math.min(inlen, need);
|
short copy;
|
||||||
|
if (inlen < need) {
|
||||||
|
copy = (short) inlen;
|
||||||
|
} else {
|
||||||
|
copy = (short) need;
|
||||||
|
}
|
||||||
|
|
||||||
System.arraycopy(in, 0, this.buf, this.buflen, copy);
|
Util.arrayCopyNonAtomic(in, (short) 0, this.buf, (short) this.buflen, copy);
|
||||||
this.buflen += copy;
|
this.buflen += copy;
|
||||||
|
|
||||||
// 调整输入指针和长度
|
// 调整输入指针和长度
|
||||||
byte[] newIn = new byte[inlen - copy];
|
byte[] newIn = new byte[inlen - copy];
|
||||||
if (inlen - copy > 0) {
|
if (inlen - copy > 0) {
|
||||||
System.arraycopy(in, copy, newIn, 0, inlen - copy);
|
Util.arrayCopyNonAtomic(in, copy, newIn, (short)0, (short) (inlen - copy));
|
||||||
}
|
}
|
||||||
in = newIn;
|
in = newIn;
|
||||||
inlen -= copy;
|
inlen -= copy;
|
||||||
@@ -65,12 +70,12 @@ public final class Zuc256EncryptCtx {
|
|||||||
putU32(out, 0, plain ^ keystream);
|
putU32(out, 0, plain ^ keystream);
|
||||||
|
|
||||||
this.buflen = 0;
|
this.buflen = 0;
|
||||||
Arrays.fill(this.buf, (byte) 0);
|
Util.arrayFillNonAtomic(this.buf, (short) 0, (short) this.buf.length, (byte) 0);
|
||||||
|
|
||||||
// 调整输出指针
|
// 调整输出指针
|
||||||
byte[] newOut = new byte[out.length - 4];
|
byte[] newOut = new byte[out.length - 4];
|
||||||
if (out.length - 4 > 0) {
|
if (out.length - 4 > 0) {
|
||||||
System.arraycopy(out, 4, newOut, 0, out.length - 4);
|
Util.arrayCopyNonAtomic(out, (short)4, newOut, (short)0, (short)(out.length - 4));
|
||||||
}
|
}
|
||||||
out = newOut;
|
out = newOut;
|
||||||
}
|
}
|
||||||
@@ -92,7 +97,7 @@ public final class Zuc256EncryptCtx {
|
|||||||
int processed = fullBlocks * 4;
|
int processed = fullBlocks * 4;
|
||||||
byte[] newIn = new byte[inlen - processed];
|
byte[] newIn = new byte[inlen - processed];
|
||||||
if (inlen - processed > 0) {
|
if (inlen - processed > 0) {
|
||||||
System.arraycopy(in, processed, newIn, 0, inlen - processed);
|
Util.arrayCopyNonAtomic(in, (short) processed, newIn, (short) 0, (short) (inlen - processed));
|
||||||
}
|
}
|
||||||
in = newIn;
|
in = newIn;
|
||||||
inlen -= processed;
|
inlen -= processed;
|
||||||
@@ -100,7 +105,7 @@ public final class Zuc256EncryptCtx {
|
|||||||
|
|
||||||
// 缓存剩余不足4字节的数据
|
// 缓存剩余不足4字节的数据
|
||||||
if (inlen > 0) {
|
if (inlen > 0) {
|
||||||
System.arraycopy(in, 0, this.buf, 0, inlen);
|
Util.arrayCopyNonAtomic(in, (short) 0, this.buf, (short) 0, (short) inlen);
|
||||||
this.buflen = inlen;
|
this.buflen = inlen;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -122,9 +127,12 @@ public final class Zuc256EncryptCtx {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 清理上下文
|
// 清理上下文
|
||||||
Arrays.fill(this.buf, (byte) 0);
|
Util.arrayFillNonAtomic(this.buf, (short) 0, (short) this.buf.length, (byte) 0);
|
||||||
this.buflen = 0;
|
this.buflen = 0;
|
||||||
Arrays.fill(this.state.LFSR, 0);
|
// 清零操作
|
||||||
|
for (short i = 0; i < (short)this.state.LFSR.length; i++) {
|
||||||
|
this.state.LFSR[i] = 0;
|
||||||
|
}
|
||||||
this.state.R1 = 0;
|
this.state.R1 = 0;
|
||||||
this.state.R2 = 0;
|
this.state.R2 = 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
package com.zuc.zuc256;
|
package com.zuc.zuc256;
|
||||||
|
|
||||||
|
import javacard.framework.Util;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 辅助工具:装载/存储、位运算、线性变换、打印等。
|
* 辅助工具:装载/存储、位运算、线性变换、打印等。
|
||||||
*/
|
*/
|
||||||
@@ -77,7 +79,9 @@ public final class Zuc256Util {
|
|||||||
if (input25Byte == null || output23Byte == null) return;
|
if (input25Byte == null || output23Byte == null) return;
|
||||||
|
|
||||||
// 复制前17字节
|
// 复制前17字节
|
||||||
System.arraycopy(input25Byte, 0, output23Byte, 0, 17);
|
// System.arraycopy(input25Byte, 0, output23Byte, 0, 17);
|
||||||
|
Util.arrayCopyNonAtomic(input25Byte, (short)0, output23Byte, (short)0, (short)17);
|
||||||
|
|
||||||
|
|
||||||
// 处理剩余8字节
|
// 处理剩余8字节
|
||||||
byte[] src = new byte[8];
|
byte[] src = new byte[8];
|
||||||
@@ -94,11 +98,11 @@ public final class Zuc256Util {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** 打印十六进制(调试用,TODO 生产/JC 环境可移除) */
|
/** 打印十六进制(调试用,TODO 生产/JC 环境可移除) */
|
||||||
public static void printHex(String label, byte[] data, int len) {
|
// public static void printHex(String label, byte[] data, int len) {
|
||||||
System.out.print(label + ": ");
|
// System.out.print(label + ": ");
|
||||||
for (int i = 0; i < len; i++) {
|
// for (int i = 0; i < len; i++) {
|
||||||
System.out.printf("%02x ", data[i] & 0xFF);
|
// System.out.printf("%02x ", data[i] & 0xFF);
|
||||||
}
|
// }
|
||||||
System.out.println();
|
// System.out.println();
|
||||||
}
|
// }
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user