Flexiprovider – 如何使用格式化的密钥对加密/ de

我使用flexiprovider来加密/ de使用基于Elliptic Curve的非对称算法,遵循本教程 。 稍加修改后,我会将公钥和私钥转换为Base64用于个人目的(如存储到数据库或文本文件中)。 我也在看这个问题 ,答案是参考这个post 。 但我的代码是运行dekstop而不是Android设备,android和dekstop版本的java我认为是一个非常大的区别(只是为了清理我的问题信息)。 好的,在我的代码中,当我要从生成的公钥创建格式化的公钥时,我收到了一个错误(我认为当我尝试为私钥执行此操作时会发生同样的问题)。 现在,这是我的代码:

  • Keypair生成器类。
import org.jivesoftware.smack.util.Base64; //or whatever to convert into Base64 import java.security.KeyPair; import java.security.KeyPairGenerator; import java.security.PrivateKey; import java.security.PublicKey; import java.security.SecureRandom; import java.security.Security; import java.security.KeyFactory; import javax.crypto.Cipher; import de.flexiprovider.common.ies.IESParameterSpec; import de.flexiprovider.core.FlexiCoreProvider; import de.flexiprovider.ec.FlexiECProvider; import de.flexiprovider.ec.parameters.CurveParams; import de.flexiprovider.ec.parameters.CurveRegistry.BrainpoolP160r1; import de.flexiprovider.pki.PKCS8EncodedKeySpec; import de.flexiprovider.pki.X509EncodedKeySpec; ... Security.addProvider(new FlexiCoreProvider()); Security.addProvider(new FlexiECProvider()); KeyPairGenerator kpg = KeyPairGenerator.getInstance("ECIES","FlexiEC"); CurveParams ecParams = new BrainpoolP160r1(); kpg.initialize(ecParams, new SecureRandom()); KeyPair keyPair = kpg.generateKeyPair(); PublicKey pubKey = keyPair.getPublic(); byte[] encod_pubK = pubKey.getEncoded(); String publicKey = Base64.encodeBytes(encod_pubK); System.out.println("Public Key :" +publikKey); PrivateKey privKey = keyPair.getPrivate(); byte[] encod_privK = privKey.getEncoded(); String privateKey = Base64.encodeBytes(encod_privK); System.out.println("Private Key :" +privateKey); 

从上面的代码我将存储字符串“privateKey”和“publicKey”。 现在我要加密消息。

  • 发件人方
 import (same as code above) ... Security.addProvider(new FlexiCoreProvider()); Security.addProvider(new FlexiECProvider()); Cipher cipher = Cipher.getInstance("ECIES","FlexiEC"); IESParameterSpec iesParams = new IESParameterSpec ("AES128_CBC","HmacSHA1", null, null); byte[] decodedPubKey = Base64.decode(publicKey); X509EncodedKeySpec formatted_public = new X509EncodedKeySpec(decodedPubKey); KeyFactory kf = KeyFactory.getInstance("ECIES","FlexiEC"); PublicKey publicKey = kf.generatePublic(formatted_public); // <--- I got error when hit this row cipher.init(Cipher.ENCRYPT_MODE, publicKey, iesParams); byte[] block = "this my message".getBytes(); System.out.println("Plaintext: "+ new String(block)); byte [] Ciphered = cipher.doFinal(block); System.out.println("Ciphertext : "+ Base64.encodeBytes(Ciphered)); 

上述发件人代码的错误是:

 Exception in thread "main" de.flexiprovider.api.exceptions.InvalidKeySpecException: java.lang.RuntimeException: java.security.InvalidAlgorithmParameterException: Caught IOException("Unknown named curve: 1.3.36.3.3.2.8.1.1.1") at de.flexiprovider.ec.keys.ECKeyFactory.generatePublic(ECKeyFactory.java:205) at de.flexiprovider.api.keys.KeyFactory.engineGeneratePublic(KeyFactory.java:39) at java.security.KeyFactory.generatePublic(KeyFactory.java:328) 

如何使用该命名曲线生成该公钥:1.3.36.3.3.2.8.1.1.1?

  • 收件人方(仅供参考)

如果发件人已成功加密邮件,现在我要解密邮件,这是我的代码(但不确定这是否运行没有错误,如上面的发件人代码):

  byte[] decodedPrivateKey = Base64.decode(privateKey); PKCS8EncodedKeySpec formatted_private = new PKCS8EncodedKeySpec(decodedPrivateKey); cipher.init(Cipher.DECRYPT_MODE, privKey, iesParams); byte[] decryptedCipher = cipher.doFinal(Ciphered); System.out.println("Decrypted message : "+ new String (decryptedCipher)); 

由于我的代码上面的未解决的错误,因为我认为这个flexiprovider与jdk-8不兼容,其中bug在“KeyFactory kf = KeyFactory.getInstance(”ECIES“,”FlexiEC“)”行中找不到命名曲线,我改变并决定使用BouncyCastle提供程序进行EC加密(ECIES),它的工作原理。 但是有一个问题再次出现在我的脑海中,正如我在Flexiprovider中看到的那样(“AES128_CBC”,“HmacSHA1”,null,null); 作为IESParameterSpec 。 但是对于bouncycastle提供商,我找不到使用AES128_CBC作为iesparameterspec的IESParameterSpec在哪里,如果我想在使用这个有弹性的提供者时将iesparam更改为AES128_CBC,我怎么能这样做呢? 有人请在有弹性的提供者中解释这个iesparam规范我是关于这个的新手。

这是我的信息代码:

  • 密钥对发电机类
 import codec.Base64; // or whatever which can use to base64 encoding import static java.lang.System.out; import java.security.KeyFactory; import java.security.KeyPair; import java.security.KeyPairGenerator; import java.security.PrivateKey; import java.security.PublicKey; import java.security.Security; import java.security.spec.ECGenParameterSpec; import java.security.spec.PKCS8EncodedKeySpec; import java.security.spec.X509EncodedKeySpec; import javax.crypto.Cipher; import org.bouncycastle.jce.provider.BouncyCastleProvider; ... Security.addProvider(new BouncyCastleProvider()); KeyPairGenerator kpg = KeyPairGenerator.getInstance("ECIES", "BC"); ECGenParameterSpec brainpoolP160R1 = new ECGenParameterSpec("brainpoolP160R1"); // I'm Still using this 160 bit GF(*p*) to keep the algorithm running fast rather than 256 or above kpg.initialize(brainpoolP160R1); KeyPair kp = kpg.generateKeyPair(); PublicKey publicKey = kp.getPublic(); PrivateKey privateKey = kp.getPrivate(); byte[] PublicKey = publicKey.getEncoded(); byte[] PrivateKey = privateKey.getEncoded(); out.println("Encoded Public : "+Base64.encode(PublicKey)); out.println("\nEncoded Private : "+Base64.encode(PrivateKey)); ... 
  • 加密类(发件人方)
 import codec.Base64; import codec.CorruptedCodeException; import java.security.InvalidKeyException; import java.security.KeyFactory; import java.security.NoSuchAlgorithmException; import java.security.NoSuchProviderException; import java.security.PublicKey; import java.security.Security; import java.security.spec.InvalidKeySpecException; import java.security.spec.X509EncodedKeySpec; import javax.crypto.BadPaddingException; import javax.crypto.Cipher; import javax.crypto.IllegalBlockSizeException; import javax.crypto.NoSuchPaddingException; import org.bouncycastle.jce.provider.BouncyCastleProvider; ... Security.addProvider(new BouncyCastleProvider()); // Assume that we know the encoded public key then return it by decode the public key byte[] decodedPublic = Base64.decode("MEIwFAYHKoZIzj0CAQYJKyQDAwIIAQEBAyoABNXclcmtUt8/rlGN47pc8ZpxkWgNgtKeeHdsVD0kIWLUMEULnchGZPA=".getBytes()); X509EncodedKeySpec formatted_public = new X509EncodedKeySpec(decodedPublic); KeyFactory kf = KeyFactory.getInstance("EC","BC"); PublicKey pubKey = kf.generatePublic(formatted_public); Cipher c = Cipher.getInstance("ECIES", "BC"); c.init(Cipher.ENCRYPT_MODE, pubKey); // How can i put the AES128_CBC for ies parameter ? is that possible byte[] cipher = c.doFinal("This is the message".getBytes()); System.out.println("Ciphertext : "+ Base64.encode(cipher)); ... 
  • 解密类(接收方)
 import codec.Base64; import codec.CorruptedCodeException; import java.security.InvalidKeyException; import java.security.KeyFactory; import java.security.NoSuchAlgorithmException; import java.security.NoSuchProviderException; import java.security.PrivateKey; import java.security.Security; import java.security.spec.InvalidKeySpecException; import java.security.spec.PKCS8EncodedKeySpec; import javax.crypto.BadPaddingException; import javax.crypto.Cipher; import javax.crypto.IllegalBlockSizeException; import javax.crypto.NoSuchPaddingException; import org.bouncycastle.jce.provider.BouncyCastleProvider; ... Security.addProvider(new BouncyCastleProvider()); // Assume that we know the encoded private key byte[] decodedPrivate = Base64.decode("MHECAQAwFAYHKoZIzj0CAQYJKyQDAwIIAQEBBFYwVAIBAQQUQmA9ifs472gNHBc5NSGYq56TlOKgCwYJKyQDAwIIAQEBoSwDKgAE1dyVya1S3z+uUY3julzxmnGRaA2C0p54d2xUPSQhYtQwRQudyEZk8A==".getBytes()); PKCS8EncodedKeySpec formatted_private = new PKCS8EncodedKeySpec(decodedPrivate); KeyFactory kf = KeyFactory.getInstance("EC", "BC"); PrivateKey privKey = kf.generatePrivate(formatted_private); Cipher c = Cipher.getInstance("ECIES"); c.init(Cipher.DECRYPT_MODE, privKey); //How can i adding the **AES128_CBC** ies param ? // Assume that we know the encoded cipher text byte[] plaintext = c.doFinal(Base64.decode("BKbCsKY7gDPld+F4jauQXvKSayYCt6vOjIGbsyXo5fHWo4Ax+Nt5BQ5FlkAGksFNRQ46agzfxjfuoxWkVfnt4gReDmpPYueUbiRiHp1Gwp0=")); System.out.println("\nPlaintext : "+ new String (plaintext)); ... 

任何帮助都会很合适!