当前位置: 首页 > 面试题库 >

Flexiprovider-如何使用格式化的密钥对加密/解密

洪高扬
2023-03-14
问题内容

按照本教程,我将使用flexiprovider基于椭圆曲线的不对称算法进行加密/解密。稍作修改,我将出于个人目的将公共密钥和私有密钥转换为Base64(例如存储到数据库或文本文件中)。但是我的代码不是在android设备中运行的,而在Java设备中运行的是dekstop,不是Java中的android和dekstop版本,我认为这是一个很大的差异(只是为了清理我的问题信息)。好的,在我的代码中,当我要从生成的公共密钥创建格式化的公共密钥时,我遇到了一个错误(我认为当我尝试为私有密钥执行相同的操作时也会发生同样的问题)。现在,这是我的代码:

  • 密钥对生成器类。
    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);

从上面的代码中,im将存储字符串“ 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不兼容,其中的错误位于“ KeyFactory kf =
KeyFactory.getInstance(“ ECIES”,“FlexiEC”)“行中,该行找不到我将其命名为曲线,然后更改并决定使用BouncyCastle提供程序进行EC加密(ECIES),并且它可以正常工作。但是我再次想到一个问题,就像我在使用的Flexiprovider中所看到的那样
(“ AES128_CBC”,“ HmacSHA1”,null,null); 作为 IESParameterSpec 。但是对于
充气城堡 提供者,我找不到 IESParameterSpec哪里
哪个使用AES128_CBC作为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));
    ...

任何帮助将是适当的!



 类似资料:
  • 这是可能的还是加密必须共享和使用相同的密钥? 主要目的就是这样。 我将有两个客户端可以发送和接收加密数据到彼此。

  • 问题内容: 我需要用openssl生成的和密钥替换从Unix到Java代码的加密和解密步骤 我生成密钥 我在Unix中使用键(我需要在Java中执行) 这是我的尝试 但它不起作用,PKCS8EncodedKeySpec / X509EncodedKeySpec不正确…但是我不知道该放什么 问题答案: 我认为您在读取PEM文件时遇到问题。JPA不直接支持PEM格式。您有两种选择,要么将它们转换为DE

  • 三个月前我得到了我应用程序的发布密钥。现在我格式化了我的计算机,当我用我的releasekey签名我的应用程序时,我得到了错误:java.lang.runtimeException:keystore Load:无效的keystore格式。 我应该如何解决这个错误? 该命令是:jarsigner-verbose-keystore“d:\releasekey.keystore”“d:\myapp.ap

  • 我正在尝试使用KMS和AWS加密SDK加密数据。查看AWS文档中提供的示例,似乎没有地方可以显式设置数据键。 使用由KMS生成的数据密钥使用AWS加密SDK加密数据的推荐方法是什么?

  • 问题内容: 我想生成rsa密钥对(公共和私有),然后将它们用于AES加密和解密。例如,用于加密的公共密钥和用于解密的私有密钥。我为此编写了一个简单的代码,但是问题是当我运行时这段代码我得到这个错误: 我该如何解决这个问题?我的加密代码如下: 问题答案: 如评论中所建议,我搜索了“混合密码术”。这个例子解决了我的问题。