From fc6a4042f7fca1828f0b8e267cfd660e6fe1d40a Mon Sep 17 00:00:00 2001 From: CGantert345 <57003061+CGantert345@users.noreply.github.com> Date: Tue, 22 Nov 2022 14:04:27 +0100 Subject: support for SSB barcodes SSB frame implenmentation including decoding, encoding, signing and verification --- .../java/org/uic/barcode/utils/SecurityUtils.java | 81 ++++++++++++++++++++++ 1 file changed, 81 insertions(+) (limited to 'src/main/java/org/uic/barcode/utils/SecurityUtils.java') diff --git a/src/main/java/org/uic/barcode/utils/SecurityUtils.java b/src/main/java/org/uic/barcode/utils/SecurityUtils.java index 5fdbda7..29a2346 100644 --- a/src/main/java/org/uic/barcode/utils/SecurityUtils.java +++ b/src/main/java/org/uic/barcode/utils/SecurityUtils.java @@ -1,5 +1,8 @@ package org.uic.barcode.utils; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.math.BigInteger; import java.security.KeyFactory; import java.security.NoSuchAlgorithmException; import java.security.PrivateKey; @@ -10,6 +13,7 @@ import java.security.Security; import java.security.spec.InvalidKeySpecException; import java.security.spec.PKCS8EncodedKeySpec; import java.security.spec.X509EncodedKeySpec; +import java.util.Arrays; /** * The Class SecurityUtils. @@ -182,4 +186,81 @@ public class SecurityUtils { return null; } + + /** + * Decode signature integer sequence. + * + * Support function to decode a DSA signature + * Provides the two DSA signature parameter encoded in a DSA signature + * + * @param bytes the bytes + * @return the big integer[] + * @throws Exception the exception + */ + public static BigInteger[] decodeSignatureIntegerSequence(byte[] bytes) throws Exception { + + int sequenceTag = (int) bytes[0]; + + if (sequenceTag != 48) throw new Exception("signature is not a sequence"); + + int sequenceLength = (int) bytes[1]; + + if (sequenceLength < 6) throw new Exception("signature sequence too short"); + + BigInteger[] result = new BigInteger[2]; + + int offset = 2; + int i = 0; + while (offset < bytes.length && i < 2) { + int integerTag = (int) bytes[offset]; + if (integerTag != 2) throw new Exception("signature is not an integer sequence"); + int integerLength = (int) bytes[offset + 1]; + byte[] value = Arrays.copyOfRange(bytes, offset + 2, offset + 2 + integerLength); + result[i] = new BigInteger(+1, value); + offset = offset + integerLength + 2; + i++; + } + + return result; + } + + /** + * Encode signature integer sequence. + * + * Support function to format two parameters as DER encoded integer list + * to get a valid formated DSA signature from the signature parameter + * + * @param i1 the i 1 + * @param i2 the i 2 + * @return the byte[] + * @throws IOException Signals that an I/O exception has occurred. + */ + public static byte[] encodeSignatureIntegerSequence(BigInteger i1, BigInteger i2) throws IOException { + + //SEQUENCE OF --> tag 16 + int sequenceTag = 16 + 32; // (bits 6 = 1 constructed) + //INTEGER --> tag 2 + int integerTag = 2; + + byte[] b1 = i1.toByteArray(); + int lb1 = b1.length; + byte[] b2 = i2.toByteArray(); + int lb2 = b2.length; + + int sequenceLength = lb1 + lb2 + 4; + + ByteArrayOutputStream out = new ByteArrayOutputStream(); + + out.write((byte) sequenceTag); + out.write((byte) sequenceLength); + out.write((byte) integerTag); + out.write((byte) lb1); + out.write(b1); + out.write((byte) integerTag); + out.write((byte) lb2); + out.write(b2); + + return out.toByteArray(); + } + } -- cgit v1.2.3 From 94d0ba8bdd36c6621e2478fdb3bcf1c790369006 Mon Sep 17 00:00:00 2001 From: CGantert345 <57003061+CGantert345@users.noreply.github.com> Date: Mon, 13 Mar 2023 13:27:13 +0100 Subject: ssb non-standard signature encoding covered (decode only) --- .../java/org/uic/barcode/utils/SecurityUtils.java | 48 ++++++++++++++++++++++ 1 file changed, 48 insertions(+) (limited to 'src/main/java/org/uic/barcode/utils/SecurityUtils.java') diff --git a/src/main/java/org/uic/barcode/utils/SecurityUtils.java b/src/main/java/org/uic/barcode/utils/SecurityUtils.java index 29a2346..8c981af 100644 --- a/src/main/java/org/uic/barcode/utils/SecurityUtils.java +++ b/src/main/java/org/uic/barcode/utils/SecurityUtils.java @@ -263,4 +263,52 @@ public class SecurityUtils { return out.toByteArray(); } + public static byte[] recombineDsaSignature(byte[] sealdata) throws IOException { + + //check whether the encoding is wrong and the sealdata contain a signature + //remove trailing zeroes from the signature + BigInteger[] bInts = null; + try { + bInts = decodeSignatureIntegerSequence(sealdata); + byte[] sig = encodeSignatureIntegerSequence(bInts[0],bInts[1]); + //decoding the entire signature was ok, so there was no split + return sig; + } catch (Exception e) { + //the signature is correctly implemented, continue with recombination + } + + // split the data into two blocks + int length = sealdata.length / 2; + byte[] rBytes = Arrays.copyOfRange(sealdata, 0, length); + byte[] sBytes = Arrays.copyOfRange(sealdata, length, length + length); + + //convert to BigInteger to get rid of leading zeroes + BigInteger r = new BigInteger(1,rBytes); + BigInteger s = new BigInteger(1,sBytes); + + //encode as DSA signature structure + //SEQUENCE OF --> tag 16 + int sequenceTag = 16 + 32; // (bits 6 = 1 constructed) + //INTEGER --> tag 2 + int integerTag = 2; + + byte[] b1 = r.toByteArray(); + int lb1 = b1.length; + + byte[] b2 = s.toByteArray(); + int lb2 = b2.length; + int sequenceLength = lb1 + lb2 + 4; + + ByteArrayOutputStream out = new ByteArrayOutputStream(); + out.write((byte) sequenceTag); + out.write((byte) sequenceLength); + out.write((byte) integerTag); + out.write((byte) lb1); + out.write(b1); + out.write((byte) integerTag); + out.write((byte) lb2); + out.write(b2); + return out.toByteArray(); + + } } -- cgit v1.2.3