如何解决如何使用 Bouncy Castle ElGamal 和 javax.crypto.Cipher 使加密 (c1, c2) 元组显式
要在java代码中使用ElGamal方案加密消息,我进行如下操作:
DECLARE
order_id_ NUMBER;
BEGIN
-- note here that you're Now assigning the return value to anything
insert_order(p_order_id => 4,p_order_num => 'O223PS56',p_name => 'Test Test',p_email => 'test@test.co.uk',p_address => '123 Test Street',p_city => 'Newcastle Upon Tyne',p_province => 'Tyne and Wear',p_postcode => 'NE98 4TN',p_telephone => '123456789',p_total => 7.97,p_order_date => to_date('11-apr-2021','DD-mon-YYYY'));
FOR i IN 1..order_items
LOOP
insert_order_items(order_id_,order_items(i) => 5,order_items(i) => 2,order_items(i) => 3073748221,order_items(i) => 'Brand New',order_items(i) => 1.99,order_items(i) => 1.99);
COMMIT;
END LOOP;
END;
/
我从 ELGamal 方案中知道 Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider());
Cipher cipher = Cipher.getInstance("Elgamal/NOne/nopadding","BC");
KeyPaireGenerator generator = KeyPairGenerator.getInstance("ElGamal","BC");
SecureRandom random = new SecureRandom();
generator.initialize(512,random);
KeyPair pair = generator.generateKeyPair();
String message = "myMessagetoEncrypt";
cipher.init(Cipher.ENCRYPT_MODE,pair.getPublic(),random);
[]byte cipherText = cipher.doFinal(message);
字节数组包含 (c1,c2) 并且我需要将 c1 作为 BigInteger 访问。
所以我的问题是:如何在字节数组和元组 (c1,c2) 之间进行转换?
谢谢
解决方法
密文的byte[]
是密钥长度的两倍,前半部分对应c0
,后半部分对应c1
。 ci
的转换是可以实现的,例如与new BigInteger(1,ci)
。
通过以这种方式转换的 BigInteger
手动执行解密,可以轻松进行验证:
int keysizeBits = 512;
Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider());
// Key generation
KeyPairGenerator generator = KeyPairGenerator.getInstance("ElGamal","BC");
SecureRandom random = new SecureRandom();
generator.initialize(keysizeBits,random);
KeyPair pair = generator.generateKeyPair();
BCElGamalPublicKey publicKey = (BCElGamalPublicKey)pair.getPublic();
BCElGamalPrivateKey privateKey = (BCElGamalPrivateKey)pair.getPrivate();
// Encryption
byte[] input = "abcdefgh".getBytes(StandardCharsets.UTF_8);
Cipher cipher = Cipher.getInstance("ElGamal/None/NoPadding","BC");
cipher.init(Cipher.ENCRYPT_MODE,publicKey,random);
byte[] ciphertext = cipher.doFinal(input);
System.out.println("Ciphertext: " + Hex.toHexString(ciphertext));//new String(cipherText));
// Decryption
cipher.init(Cipher.DECRYPT_MODE,privateKey);
byte[] plaintext = cipher.doFinal(ciphertext);
System.out.println("Plaintext : " + new String(plaintext,StandardCharsets.UTF_8));
// Manual decryption
// 1. Convert c0/c1 into BigInteger
byte[] c0 = new byte[keysizeBits/8];
byte[] c1 = new byte[keysizeBits/8];
System.arraycopy(ciphertext,c0,keysizeBits/8);
System.arraycopy(ciphertext,c0.length,c1,keysizeBits/8);
System.out.println("c0 : " + Hex.toHexString(c0));
System.out.println("c1 : " + Hex.toHexString(c1));
BigInteger c0BI = new BigInteger(1,c0);
BigInteger c1BI = new BigInteger(1,c1);
// 2. Decrypt with c0BI^(-privBI) * c1BI
BigInteger privateKeyBI = privateKey.getX();
BigInteger pBI = privateKey.getParameters().getP();
BigInteger plaintextBI = c0BI.modPow(privateKeyBI.multiply(new BigInteger("-1")),pBI).multiply(c1BI).mod(pBI);
System.out.println("Plaintext : " + new String(plaintextBI.toByteArray(),StandardCharsets.UTF_8));
例如以下输出:
Ciphertext: adc32bbd23d80489db5843e26b26c58062a2369912915025574fd8598b8c72665e0a922ad8897719e1f9b0e3fb76e275ed15194534399781017e43c24a92cc77b13a256ff27e12667cc0f5876d1873368449b5a60ecc7a60a6b92f2640608f21dc86e7effe1dc4038b02b8c6c9d7ac03bd2e7d66d803d2a19f459ffeedfcff46
Plaintext : abcdefgh
c0 : adc32bbd23d80489db5843e26b26c58062a2369912915025574fd8598b8c72665e0a922ad8897719e1f9b0e3fb76e275ed15194534399781017e43c24a92cc77
c1 : b13a256ff27e12667cc0f5876d1873368449b5a60ecc7a60a6b92f2640608f21dc86e7effe1dc4038b02b8c6c9d7ac03bd2e7d66d803d2a19f459ffeedfcff46
Plaintext : abcdefgh
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。