源码:https://github.com/yanjunli/eos-crypto-java
eos-crypto-java 目前可以支持 基于 ECC+AES 的加解密方式。
在本压缩包中,包含基于jdk1.5 打好的jar 包。
jdk 1.5+
String privateKey = "5KTZYCDdcfNrmEpcf97SJBCtToZjYHjHm8tqTWvzUbsUJgkxcfk"; EosPrivateKey eosPrivateKey = new EosPrivateKey(privateKey); EosPublicKey eosPublicKey = eosPrivateKey.getPublicKey(); // 转换成 EC privatekey ECPrivateKey ecPrivateKey = eosPrivateKey.getECPrivateKey(); ECPublicKey ecPublicKey = eosPublicKey.getECPublicKey(); byte[] plaindata = "{\"age\": 1,\"12345\":\"24qqwazzxdtttdxkaskjewuizckczxnlsdosasda4!!!@#$$%^&&*(()(^#\"}".getBytes("utf8"); System.out.println("加密原文:" + new String(plaindata)); byte[] encryptdata = ECCUtil.publicEncrypt(plaindata,ecPublicKey); System.out.println("加密后密文:" + HexUtils.toHex(encryptdata)); plaindata = ECCUtil.privateDecrypt(encryptdata,ecPrivateKey); System.out.println("解密后原文: "+ new String(plaindata));
/** * * sender 发起方密钥对 * * EOS8g1u3ktAGHs4QsVp9aeaWNebFLtprQHwpaSjegx6iEuoTNhjXU * 5KTZYCDdcfNrmEpcf97SJBCtToZjYHjHm8tqTWvzUbsUJgkxcfk * * receiver 接收方一密钥对 * * EOS7ez2gagfoXw9XdW3kRx3EsCoWvupGR6u6ZJhFPEe9Q12V8JgUL * 5JUrqxYcssR9LLVtWDeQcc9HCX4FEqBG7d9GW6t7mvmB1rUuZr9 * * receiver 接收方二 密钥对 * EOS5WMHqw6jDDBPBm7JXTHemAwtSo2tp93pRysJMRhiT1zUYb24vL * 5HrcVeuHHNwHsivrMoJ9XvU6EM7Q2wQ2ECiy8GeoiuamhNiSuZq */ // 1. 调用钱包获取 发送方私钥 String senderPrivateKey = "5KTZYCDdcfNrmEpcf97SJBCtToZjYHjHm8tqTWvzUbsUJgkxcfk"; EosPrivateKey senderECPrivateKey = new EosPrivateKey(senderPrivateKey); // EosPublicKey senderECPublicKey = new EosPublicKey(senderPublicKey); // 2. 根据私钥 生成公钥。 或者直接根据公钥 调用钱包获取私钥。 都可以。 EosPublicKey senderECPublicKey = senderECPrivateKey.getPublicKey(); String senderPublicKey = senderECPublicKey.toString(); /** * 调用钱包获取 接收方私钥 获取公私钥方式 根据需求确定。 * 1. 可以根据公钥,从钱包里获取私钥 * 2. 也可以直接从钱包里取出私钥,反向生成公钥 * * 实际业务场景,发起方只会有接收方公钥,并没有接收方私钥. * 此时 可以通过 new EosPublicKey(receiverPublicKey) 方式 生成EosPublicKey 对象。 */ String receiverPrivateKey = "5JUrqxYcssR9LLVtWDeQcc9HCX4FEqBG7d9GW6t7mvmB1rUuZr9"; EosPrivateKey receiverECPrivateKey = new EosPrivateKey(receiverPrivateKey); EosPublicKey receiverECPublicKey = receiverECPrivateKey.getPublicKey(); String receiverPublicKey = receiverECPublicKey.toString(); // String receiverPublicKey = "EOS7ez2gagfoXw9XdW3kRx3EsCoWvupGR6u6ZJhFPEe9Q12V8JgUL"; /** * 使用 发送者方私钥 和接收方公钥,生成 aes key, 对数据进行加密 * nonce 为初始化向量,可以使用固定值, * 也可以使用随机值,并使用私有协议。根据业务需求选择。 */ byte[] nonce = new byte[16]; MTRandom random=new MTRandom(); random.nextBytes(nonce); // 待加密 数据 byte[] params = "{\"test1\": 1,\"test2\":\"24qqwazzxdtttdxkaskjewuizckczxnlsdosasda4!!!@#$$%^&&*((){}(^#\"}".getBytes("utf8"); System.out.println("原始加密数据: " + new String(params,"utf8")); byte[] encrypted = new byte[0]; try { encrypted = CryptUtil.encrypt(senderECPrivateKey,receiverECPublicKey,nonce,params); } catch (InvalidCipherTextException e) { e.printStackTrace(); System.out.println(" do something!!!!"); } System.out.println("加密后数据: " + new String(encrypted,"utf8")); try { byte[] plainText = CryptUtil.decrypt(receiverECPrivateKey,senderECPublicKey,nonce,encrypted); // 解密后数据 System.out.println("解密后数据 : "+new String(plainText, "utf8")); } catch (InvalidCipherTextException e) { e.printStackTrace(); System.out.println(" do something!!!!"); }
/** * * sender * * EOS8g1u3ktAGHs4QsVp9aeaWNebFLtprQHwpaSjegx6iEuoTNhjXU * 5KTZYCDdcfNrmEpcf97SJBCtToZjYHjHm8tqTWvzUbsUJgkxcfk * * receiver 平台公私钥对 * * EOS7ez2gagfoXw9XdW3kRx3EsCoWvupGR6u6ZJhFPEe9Q12V8JgUL * 5JUrqxYcssR9LLVtWDeQcc9HCX4FEqBG7d9GW6t7mvmB1rUuZr9 * * receiver 省侧公私钥对 * EOS5WMHqw6jDDBPBm7JXTHemAwtSo2tp93pRysJMRhiT1zUYb24vL * 5HrcVeuHHNwHsivrMoJ9XvU6EM7Q2wQ2ECiy8GeoiuamhNiSuZq */ // 1. 调用钱包获取 发送方私钥 String senderPrivateKey = "5KTZYCDdcfNrmEpcf97SJBCtToZjYHjHm8tqTWvzUbsUJgkxcfk"; EosPrivateKey senderECPrivateKey = new EosPrivateKey(senderPrivateKey); // EosPublicKey senderECPublicKey = new EosPublicKey(senderPublicKey); // 2. 根据私钥 生成公钥。 或者直接根据公钥 调用钱包获取私钥。 都可以,看具体业务需求 EosPublicKey senderECPublicKey = senderECPrivateKey.getPublicKey(); String senderPublicKey = senderECPublicKey.toString(); /** * 调用钱包获取 接收方私钥 获取公私钥方式 根据业务需求确定。 * 1. 可以根据公钥,从钱包里获取私钥 * 2. 也可以直接从钱包里取出私钥,反向生成公钥 */ String receiverPrivateKey = "5JUrqxYcssR9LLVtWDeQcc9HCX4FEqBG7d9GW6t7mvmB1rUuZr9"; EosPrivateKey receiverECPrivateKey = new EosPrivateKey(receiverPrivateKey); EosPublicKey receiverECPublicKey = receiverECPrivateKey.getPublicKey(); /** * 生成对称密钥 */ byte[] nonce = new byte[16]; MTRandom random=new MTRandom(); random.nextBytes(nonce); // 待加密 数据 byte[] params = "{\"age\": 1,\"汉字\":\"为初始化向量,可以使用固定值,\",\"12345\":\"24qqwazzxdtttdxkaskjewuizckczxnlsdosasda4!!!@#$$%^&&*(()(^#\"}".getBytes("utf8"); System.out.println("加密前原始数据: " + new String(params,"utf8")); // 发起方使用对称密钥,对原始数据进行加密 byte[] encryptedData = null; try { encryptedData = CryptUtil.aesEncryptWithNOIV(nonce,params); } catch (InvalidCipherTextException e) { e.printStackTrace(); System.out.println(" do something!!!!"); } System.out.println("加密后数据: " + HexUtils.toHex(encryptedData)); System.out.println("加密前对称密钥: " + HexUtils.toHex(nonce)); // 发起方使用 接收方公钥,对对称密钥进行加密 byte[] encryptedKey = null; try { encryptedKey = ECCUtil.publicEncrypt(nonce,receiverECPublicKey.getECPublicKey()); } catch (Exception e) { e.printStackTrace(); System.out.println(" do something!!!!"); } System.out.println("加密后对称密钥: " + HexUtils.toHex(encryptedKey)); // 将对称密钥加密后的数据,密文组装后,进行网络传输。 // 组装 demo /** * 4 byte | encryptedKey | 4 byte | encryptedData * 对称密钥加密后的数据长度 | ECC 加密后的对称秘钥 | 密文数据长度 | AES 加密后的密文 */ ByteBuffer bytebuffer = ByteBuffer.allocate( 4 + encryptedKey.length + 4 +encryptedData.length); bytebuffer.putInt(encryptedKey.length); bytebuffer.put(encryptedKey); bytebuffer.putInt(encryptedData.length); bytebuffer.put(encryptedData); // String base58encode = Base58.encode(bytebuffer.array()); // System.out.println("base58 编码后的: " + base58encode); // 进行 16 进制编码 String hexencode = HexUtils.toHex(bytebuffer.array()); System.out.println(" 将数字信封和密文组装后的报文 16进制格式:" + hexencode); System.out.println("发送方数据加密完成,可以将数据发送出去 "); /** ***************************************************** 以下为接收方 代码 ************************************* */ // byte[] base58decode = Base58.decode(hexencode); byte[] hexdecode = HexUtils.toBytes(hexencode); ByteBuffer receiveBuffer = ByteBuffer.wrap(hexdecode); // 获取到对称秘钥长度 int receivedEncryptedKeyLength = receiveBuffer.getInt(); // 加密后的对称密钥key byte[] receivedEncryptKey = new byte[receivedEncryptedKeyLength]; receiveBuffer.get(receivedEncryptKey,0,receivedEncryptedKeyLength); System.out.println(" 接收到的 加密后的对称密钥 :" + HexUtils.toHex(receivedEncryptKey)); // 获取到的 密文的长度 int contextLength = receiveBuffer.getInt(); // 密文 byte[] receivedEncryptContext = new byte[contextLength]; receiveBuffer.get(receivedEncryptContext,0,contextLength); System.out.println(" 接收到的 密文:" + HexUtils.toHex(receivedEncryptContext)); // 使用接收方私钥,解密对称密钥 byte[] receiveddecryptKey = null; try { receiveddecryptKey = ECCUtil.privateDecrypt(receivedEncryptKey,receiverECPrivateKey.getECPrivateKey()); } catch (Exception e) { e.printStackTrace(); System.out.println(" do something!!!!"); } System.out.println(" 解密后的对称密钥 :" + HexUtils.toHex(receiveddecryptKey)); // 使用对称密钥,对密文进行解密 try { byte[] plainText = CryptUtil.aesDecryptWithNOIV(receiveddecryptKey,receivedEncryptContext); // 解密后数据 System.out.println("解密后数据 : "+new String(plainText, "utf8")); } catch (InvalidCipherTextException e) { e.printStackTrace(); System.out.println(" do something!!!!"); }
/** * 16 进制 交易数据 */ String hexData = "6a3f0e5f210a14b478050000000001603463937a4c8f440000b82a5d5a91d401809fd18c4dea8f4400000020476d964aa701809fd18c4dea8f440f495ab51e9cb44908424f53533130303008554d43503130303004554d43501f3533314249503242333235323032303034313531363238323231353336363908ab91465f12000006017560c95d040000007560c95d0400000000000000000000000100000000000000080006323130303130c818f4515f12000040035df1481b000006363938303237082d4359313647424e0200000000000000000000000000"; /** * eos 签名 */ String signStr = "SIG_K1_K1Pgvc9jXrCbPXx23zGugEfhxcGXoCSJjFEzFQj2HoFie18qnizWzQGssQezmS8PZ9fkKci3k8PGM2MQpJvuXtRZtd4oCD"; EcSignature ecSignature = new EcSignature(signStr); Sha256 curData = getDigestForSignature(new TypeChainId("4a2fb7b7aacce5ea952dc96fbac6ed648efc08c1e1577882f3f33c82da248d64"),hexData); /** * 恢复公钥 */ EosPublicKey eosPublicKey = EcDsa.recoverPubKey(curData.getBytes(), ecSignature); System.out.println("publicKey: " + eosPublicKey.toString()); /** * 验证 恢复出来的公钥,与原公钥是否相同 */ Assert.assertEquals("EOS4wTJSTd29mZ4MNPZ2y4q2PtrimVpHLwHg8U4XMdzSBLa4BeYmN",eosPublicKey.toString());