/** * Returns public key point from the given private key. * * @param privKey the private key to derive the public key from * @return ECPoint public key */ public static ECPoint publicPointFromPrivate(BigInteger privKey) { /* * TODO: FixedPointCombMultiplier currently doesn't support scalars longer than the group * order, but that could change in future versions. */ if (privKey.bitLength() > CURVE.getN().bitLength()) { privKey = privKey.mod(CURVE.getN()); } return new FixedPointCombMultiplier().multiply(CURVE.getG(), privKey); }
@Override public InputStream newCipherInputStream(InputStream underlyingInputStream, byte[] secretKey, byte[] iv) throws CipherException { AEADBlockCipher cipher = new GCMBlockCipher(new TwofishEngine()); cipher.init(false, new AEADParameters(new KeyParameter(secretKey), MAC_SIZE, iv)); return new org.bouncycastle.crypto.io.CipherInputStream(underlyingInputStream, cipher); } }
/** Decompress a compressed public key (x co-ord and low-bit of y-coord). */ private static ECPoint decompressKey(BigInteger xBN, boolean yBit) { X9IntegerConverter x9 = new X9IntegerConverter(); byte[] compEnc = x9.integerToBytes(xBN, 1 + x9.getByteLength(CURVE.getCurve())); compEnc[0] = (byte)(yBit ? 0x03 : 0x02); return CURVE.getCurve().decodePoint(compEnc); }
public static byte[] hmacSha512(byte[] key, byte[] input) { HMac hMac = new HMac(new SHA512Digest()); hMac.init(new KeyParameter(key)); hMac.update(input, 0, input.length); byte[] out = new byte[64]; hMac.doFinal(out, 0); return out; }
private byte[] generateKey(byte[] salt) throws UnsupportedEncodingException { PKCS5S2ParametersGenerator gen = new PKCS5S2ParametersGenerator(new SHA256Digest()); gen.init(this.passphrase.getBytes("UTF-8"), salt, PBKDF2_ITERATIONS); return ((KeyParameter) gen.generateDerivedParameters(AES_KEY_LENGTH_BITS)).getKey(); } }
@Override public byte[] encrypt(byte[] bytes) { byte[] iv = this.ivGenerator.generateKey(); @SuppressWarnings("deprecation") PaddedBufferedBlockCipher blockCipher = new PaddedBufferedBlockCipher( new CBCBlockCipher(new org.bouncycastle.crypto.engines.AESFastEngine()), new PKCS7Padding()); blockCipher.init(true, new ParametersWithIV(secretKey, iv)); byte[] encrypted = process(blockCipher, bytes); return iv != null ? concatenate(iv, encrypted) : encrypted; }
@Override public byte[] encrypt(byte[] bytes) { byte[] iv = this.ivGenerator.generateKey(); @SuppressWarnings("deprecation") GCMBlockCipher blockCipher = new GCMBlockCipher(new org.bouncycastle.crypto.engines.AESFastEngine()); blockCipher.init(true, new AEADParameters(secretKey, 128, iv, null)); byte[] encrypted = process(blockCipher, bytes); return iv != null ? concatenate(iv, encrypted) : encrypted; }
/** * 用私钥对信息生成数字签名 * * @param data 加密数据 * @param id 可以为null,若为null,则默认withId为字节数组:"1234567812345678".getBytes() * @return 签名 */ public byte[] sign(byte[] data, byte[] id) { lock.lock(); if (null == this.signer) { this.signer = new SM2Signer(); } final SM2Signer signer = this.signer; try { CipherParameters param = new ParametersWithRandom(generateCipherParameters(KeyType.PrivateKey)); if (id != null) { param = new ParametersWithID(param, id); } signer.init(true, param); signer.update(data, 0, data.length); return signer.generateSignature(); } catch (Exception e) { throw new CryptoException(e); } finally { lock.unlock(); } }
/** * Sign a hash with the private key of this key pair. * @param transactionHash the hash to sign * @return An {@link ECDSASignature} of the hash */ public ECDSASignature sign(byte[] transactionHash) { ECDSASigner signer = new ECDSASigner(new HMacDSAKCalculator(new SHA256Digest())); ECPrivateKeyParameters privKey = new ECPrivateKeyParameters(privateKey, Sign.CURVE); signer.init(true, privKey); BigInteger[] components = signer.generateSignature(transactionHash); return new ECDSASignature(components[0], components[1]).toCanonicalised(); }
/** * Will automatically adjust the S component to be less than or equal to half the curve * order, if necessary. This is required because for every signature (r,s) the signature * (r, -s (mod N)) is a valid signature of the same message. However, we dislike the * ability to modify the bits of a Bitcoin transaction after it's been signed, as that * violates various assumed invariants. Thus in future only one of those forms will be * considered legal and the other will be banned. * * @return the signature in a canonicalised form. */ public ECDSASignature toCanonicalised() { if (!isCanonical()) { // The order of the curve is the number of valid points that exist on that curve. // If S is in the upper half of the number of valid points, then bring it back to // the lower half. Otherwise, imagine that // N = 10 // s = 8, so (-8 % 10 == 2) thus both (r, 8) and (r, 2) are valid solutions. // 10 - 8 == 2, giving us always the latter solution, which is canonical. return new ECDSASignature(r, Sign.CURVE.getN().subtract(s)); } else { return this; } } }
/** * Creates a derived key from the given input key material (raw byte array) and an input salt * and wraps the key in a {@link SecretKeySpec} using the given output key algorithm and output * key size. * * <p>The algorithm used to derive the new key from the input key material (IKM) is the * <b>HMAC-based Extract-and-Expand Key Derivation Function (HKDF)</b> (see * <a href="http://tools.ietf.org/html/rfc5869">RFC 5869</a>) * * @param inputKeyMaterial The input key material as raw data bytes, e.g. determined from {@link SecretKey#getEncoded()} * @param inputSalt Input salt used to generate the new key (a non-secret random value!) * @param outputKeyAlgorithm Defines the algorithm of the new output key (for {@link SecretKeySpec#getAlgorithm()}) * @param outputKeySize Defines the key size of the new output key * @return Returns a new pseudorandom key derived from the input key material using HKDF * @see <a href="http://tools.ietf.org/html/rfc5869">RFC 5869</a> */ public static SaltedSecretKey createDerivedKey(byte[] inputKeyMaterial, byte[] inputSalt, String outputKeyAlgorithm, int outputKeySize) throws InvalidKeySpecException, NoSuchAlgorithmException, NoSuchProviderException { HKDFBytesGenerator hkdf = new HKDFBytesGenerator(KEY_DERIVATION_DIGEST); hkdf.init(new HKDFParameters(inputKeyMaterial, inputSalt, KEY_DERIVATION_INFO)); byte[] derivedKey = new byte[outputKeySize / 8]; hkdf.generateBytes(derivedKey, 0, derivedKey.length); return toSaltedSecretKey(derivedKey, inputSalt, outputKeyAlgorithm); }
@Override public OutputStream newCipherOutputStream(OutputStream underlyingOutputStream, byte[] secretKey, byte[] iv) throws CipherException { AEADBlockCipher cipher = new GCMBlockCipher(new AESEngine()); cipher.init(true, new AEADParameters(new KeyParameter(secretKey), MAC_SIZE, iv)); return new org.bouncycastle.crypto.io.CipherOutputStream(underlyingOutputStream, cipher); }
private static String encrypt(byte[] key, String plainText) throws CryptoException { try { PaddedBufferedBlockCipher cipher = new PaddedBufferedBlockCipher(new CBCBlockCipher(new DESEngine())); KeyParameter keyParameter = new KeyParameter(key); cipher.init(true, keyParameter); byte[] plainTextBytes = plainText.getBytes(); byte[] cipherTextBytes = new byte[cipher.getOutputSize(plainTextBytes.length)]; int outputLength = cipher.processBytes(plainTextBytes, 0, plainTextBytes.length, cipherTextBytes, 0); cipher.doFinal(cipherTextBytes, outputLength); return ENCODER.encodeToString(cipherTextBytes).trim(); } catch (Exception e) { throw new CryptoException(e); } }
private static byte[] generateAes128CtrDerivedKey( byte[] password, byte[] salt, int c, String prf) throws CipherException { if (!prf.equals("hmac-sha256")) { throw new CipherException("Unsupported prf:" + prf); } // Java 8 supports this, but you have to convert the password to a character array, see // http://stackoverflow.com/a/27928435/3211687 PKCS5S2ParametersGenerator gen = new PKCS5S2ParametersGenerator(new SHA256Digest()); gen.init(password, salt, c); return ((KeyParameter) gen.generateDerivedParameters(256)).getKey(); }
@Override public byte[] encrypt(byte[] bytes) { byte[] iv = this.ivGenerator.generateKey(); @SuppressWarnings("deprecation") GCMBlockCipher blockCipher = new GCMBlockCipher(new org.bouncycastle.crypto.engines.AESFastEngine()); blockCipher.init(true, new AEADParameters(secretKey, 128, iv, null)); byte[] encrypted = process(blockCipher, bytes); return iv != null ? concatenate(iv, encrypted) : encrypted; }
/** * 用私钥对信息生成数字签名 * * @param data 加密数据 * @param id 可以为null,若为null,则默认withId为字节数组:"1234567812345678".getBytes() * @return 签名 */ public byte[] sign(byte[] data, byte[] id) { lock.lock(); if (null == this.signer) { this.signer = new SM2Signer(); } final SM2Signer signer = this.signer; try { CipherParameters param = new ParametersWithRandom(generateCipherParameters(KeyType.PrivateKey)); if (id != null) { param = new ParametersWithID(param, id); } signer.init(true, param); signer.update(data, 0, data.length); return signer.generateSignature(); } catch (Exception e) { throw new CryptoException(e); } finally { lock.unlock(); } }
@Override public OutputStream newCipherOutputStream(OutputStream underlyingOutputStream, byte[] secretKey, byte[] iv) throws CipherException { AEADBlockCipher cipher = new GCMBlockCipher(new TwofishEngine()); cipher.init(true, new AEADParameters(new KeyParameter(secretKey), MAC_SIZE, iv)); return new org.bouncycastle.crypto.io.CipherOutputStream(underlyingOutputStream, cipher); }
@Override public byte[] decrypt(byte[] encryptedBytes) { byte[] iv = subArray(encryptedBytes, 0, this.ivGenerator.getKeyLength()); encryptedBytes = subArray(encryptedBytes, this.ivGenerator.getKeyLength(), encryptedBytes.length); @SuppressWarnings("deprecation") GCMBlockCipher blockCipher = new GCMBlockCipher(new org.bouncycastle.crypto.engines.AESFastEngine()); blockCipher.init(false, new AEADParameters(secretKey, 128, iv, null)); return process(blockCipher, encryptedBytes); }
@Override public InputStream newCipherInputStream(InputStream underlyingInputStream, byte[] secretKey, byte[] iv) throws CipherException { AEADBlockCipher cipher = new GCMBlockCipher(new AESEngine()); cipher.init(false, new AEADParameters(new KeyParameter(secretKey), MAC_SIZE, iv)); return new org.bouncycastle.crypto.io.CipherInputStream(underlyingInputStream, cipher); } }
@Override public byte[] decrypt(byte[] encryptedBytes) { byte[] iv = subArray(encryptedBytes, 0, this.ivGenerator.getKeyLength()); encryptedBytes = subArray(encryptedBytes, this.ivGenerator.getKeyLength(), encryptedBytes.length); @SuppressWarnings("deprecation") GCMBlockCipher blockCipher = new GCMBlockCipher(new org.bouncycastle.crypto.engines.AESFastEngine()); blockCipher.init(false, new AEADParameters(secretKey, 128, iv, null)); return process(blockCipher, encryptedBytes); }