Java tutorial
//package com.java2s; import java.math.BigInteger; public class Main { /** * http://download.oracle.com/javase/1.5.0/docs/guide/security/CryptoSpec.html * Signature Format ASN.1 sequence of two INTEGER values: r and s, in that order: * SEQUENCE ::= { r INTEGER, s INTEGER } * * http://en.wikipedia.org/wiki/Abstract_Syntax_Notation_One * 30 -- tag indicating SEQUENCE * xx - length in octets * * 02 -- tag indicating INTEGER * xx - length in octets * xxxxxx - value * * Convert to BigInteger and back so we have the minimum length representation, as required. * r and s are always non-negative. * * Only supports sigs up to about 252 bytes. See code to fix BER encoding for this before you * add a SigType with bigger signatures. * * @throws IllegalArgumentException if too big * @since 0.8.7, moved to SigUtil in 0.9.9 */ private static byte[] sigBytesToASN1(byte[] sig) { //System.out.println("pre TO asn1\n" + net.i2p.util.HexDump.dump(sig)); int len = sig.length; int sublen = len / 2; byte[] tmp = new byte[sublen]; System.arraycopy(sig, 0, tmp, 0, sublen); BigInteger r = new BigInteger(1, tmp); byte[] rb = r.toByteArray(); if (rb.length > 127) throw new IllegalArgumentException("FIXME R length > 127"); System.arraycopy(sig, sublen, tmp, 0, sublen); BigInteger s = new BigInteger(1, tmp); byte[] sb = s.toByteArray(); if (sb.length > 127) throw new IllegalArgumentException("FIXME S length > 127"); int seqlen = rb.length + sb.length + 4; if (seqlen > 255) throw new IllegalArgumentException("FIXME seq length > 255"); int totlen = seqlen + 2; if (seqlen > 127) totlen++; byte[] rv = new byte[totlen]; int idx = 0; rv[idx++] = 0x30; if (seqlen > 127) rv[idx++] = (byte) 0x81; rv[idx++] = (byte) seqlen; rv[idx++] = 0x02; rv[idx++] = (byte) rb.length; System.arraycopy(rb, 0, rv, idx, rb.length); idx += rb.length; rv[idx++] = 0x02; rv[idx++] = (byte) sb.length; System.arraycopy(sb, 0, rv, idx, sb.length); //System.out.println("post TO asn1\n" + net.i2p.util.HexDump.dump(rv)); return rv; } }