【问题标题】:BouncyCastle J2ME RSA using custom keys使用自定义密钥的 BouncyCastle J2ME RSA
【发布时间】:2012-03-20 23:37:05
【问题描述】:

我想在我的 Blackberry 应用程序中使用 BouncyCastle J2ME/RIM Crypto。

我遇到的问题是我想从 C#.NET 程序生成用于加密的公钥,该程序将密钥发送到 BlackBerry。

是否可以使用原始字符串加密消息?另外,我是否需要知道其他常见变量,例如模数等?抱歉,但我对密码算法完全陌生。

我需要 BouncyCastle 还是可以使用 RIM Crypto 完成以上操作?

谢谢, 康纳

【问题讨论】:

    标签: blackberry cryptography rsa bouncycastle public-key-encryption


    【解决方案1】:

    我是使用 bouncycastle 完成的,但与 RIM Crypto 类似。 根据例子。如您所见,键是字符串...:

        public CypherDecypherExample()
       {        
        String plain    ="a plain string";
        String cipher   = null;
        String decipher = null;
        byte [] byte_cipher = null;
        byte [] byte_plain  = null;
    
        // key           |-- 128 bit -->|-- 256 bit --->|
        String key    = "aaaaaaaaaaaaaaaacccccccccccccccc";
        String iv     = "bbbbbbbbbbbbbbbb";
    
    System.out.println("bouncycastle.plain: " + plain);
    
        try {
            byte_cipher = encrypt(plain.getBytes(), key.getBytes(), iv.getBytes());
            cipher = new String(byte_cipher);
            System.out.println("bouncycastle.cipher: " + cipher);
    
        } catch (Exception e) {
            e.printStackTrace();
        }
    
    
        try {
            byte_plain = decrypt(byte_cipher, key.getBytes(), iv.getBytes());
            decipher = new String(byte_plain);
            System.out.println("bouncycastle.decipher: " + decipher);
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    
    } 
    
    private static byte[] cipherData(PaddedBufferedBlockCipher cipher, byte[] data)
    throws Exception
    {
        String plain = new String(data);
        System.out.println("bouncycastle.cipherData: " + plain);
    
        int minSize = cipher.getOutputSize(data.length);
        byte[] outBuf = new byte[minSize];
        int length1 = cipher.processBytes(data, 0, data.length, outBuf, 0);
        int length2 = cipher.doFinal(outBuf, length1);
        int actualLength = length1 + length2;
        byte[] result = new byte[actualLength];
        System.arraycopy(outBuf, 0, result, 0, result.length);
    
    System.out.println("bouncycastle.cipherData returning");
    
        return result;
    }
    
    private static byte[] decrypt(byte[] cipher, byte[] key, byte[] iv) throws Exception
    {
        PaddedBufferedBlockCipher aes = new PaddedBufferedBlockCipher((BlockCipher) new CBCBlockCipher(
                new AESEngine()));
        CipherParameters ivAndKey = new ParametersWithIV(new KeyParameter(key), iv);
        aes.init(false, ivAndKey);
        return cipherData(aes, cipher);
    }
    
    private static byte[] encrypt(byte[] plain, byte[] key, byte[] iv) throws Exception
    {       
        PaddedBufferedBlockCipher aes = new PaddedBufferedBlockCipher(new CBCBlockCipher(
                new AESEngine()));
    
        CipherParameters ivAndKey = new ParametersWithIV(new KeyParameter(key), iv);
    
        aes.init(true, ivAndKey);
    
        return cipherData(aes, plain);
    }
    

    【讨论】:

    • 谢谢。 128Bit、256Bit是什么意思?还有什么是iv,(初始化向量)?我如何生成这个?谢谢。
    • 如果要使用 128 位密钥,请以 128 位符号(前 16 个字符)结束字符串。如果您更喜欢 256 位密钥,请使用 32 个字符。 iv 是另一个字符串(由您选择)。我不是加密专家...
    • 你不应该使用键作为字符串,你不应该在没有指定编码的情况下使用getBytes。
    • 如何将这个充气城堡添加到我的项目中?只包括罐子?
    • 我从 jar 文件中提取了项目所需的文件子集,然后将它们作为“普通”文件包含在项目中。
    【解决方案2】:

    一个 RSA 公钥由两部分组成,而不是像我想象的那样。

    ExponentModulus。这些都是数字,但我将它们作为 Base64 字符串从 .NET 客户端传递给 Blackberry,并在 RIM Crypto 函数使用它们时将它们解码为字节数组,因为它们将字节数组作为参数。

    byte[] exponent = Base64InputStream.decode("exponent base64 string");
    byte[] modulus = Base64InputStream.decode("modulus base64 string");
    
    NoCopyByteArrayOutputStream cipherUserData = new NoCopyByteArrayOutputStream();             
    RSACryptoSystem cryptoSystem = new RSACryptoSystem(1024);
    
    // Create Public key using your variables from before
    RSAPublicKey publicKey = new RSAPublicKey( cryptoSystem, exponent, modulus);
    
    // Encryption engine objects
    RSAEncryptorEngine eEngine = new RSAEncryptorEngine(publicKey);
    PKCS1FormatterEngine fEngine = new PKCS1FormatterEngine(eEngine);
    BlockEncryptor cryptoStream = new BlockEncryptor(fEngine, cipherUserData);  
    
    
    // Read the user data and encrypt while doing so. Remember, cryptoStream writes its data to
    // cipherUserData so this is where the encrypted version of userData will end up.
    cryptoStream.write( userData, 0, userData.length );
    
    cryptoStream.close();
    cipherUserData.close();
    
    String encryptedUserData = new String(cipherUserData.toByteArray());
    

    伙计们,这几乎就是所有内容了,这很简单,但我花了很长时间才从 API 文档中得到它 :)

    重要提示 RSA 仅限于加密目的,因为您只能加密

    我在上面写的东西花了好几天的时间修修补补和阅读。我希望它可以帮助某人更快地实现他们的目标。 :)

    【讨论】:

      猜你喜欢
      • 2015-03-21
      • 2021-10-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-06-15
      • 2016-07-10
      • 1970-01-01
      相关资源
      最近更新 更多