Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/400.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
AES PBE在Java中加密/在Ruby中解密_Java_Ruby_Cryptography_Encryption - Fatal编程技术网

AES PBE在Java中加密/在Ruby中解密

AES PBE在Java中加密/在Ruby中解密,java,ruby,cryptography,encryption,Java,Ruby,Cryptography,Encryption,使用Bouncy Castle PBewithsha256和128位AES-CBC-BC算法在Java中加密字符串数据。很难用ruby解密。我见过一些类似操作的例子,但没有一个是在JavaPBEkeySpect中使用的(当然不确定这是否是问题所在)。对于某些上下文,这里是Java代码 SecretKeyFactory factory = SecretKeyFactory.getInstance("PBEWITHSHA256AND128BITAES-CBC-BC",

使用Bouncy Castle PBewithsha256和128位AES-CBC-BC算法在Java中加密字符串数据。很难用ruby解密。我见过一些类似操作的例子,但没有一个是在JavaPBEkeySpect中使用的(当然不确定这是否是问题所在)。对于某些上下文,这里是Java代码

    SecretKeyFactory factory = SecretKeyFactory.getInstance("PBEWITHSHA256AND128BITAES-CBC-BC", 
            org.spongycastle.jce.provider.BouncyCastleProvider.PROVIDER_NAME);

    KeySpec spec = new PBEKeySpec("password".toCharArray(), 
            "8 bytes!", 1024, 128);

    SecretKey tmp = factory.generateSecret(spec);
    SecretKey secret = new SecretKeySpec(tmp.getEncoded(), "AES");

    Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
    cipher.init(Cipher.ENCRYPT_MODE, secret);
    AlgorithmParameters params = cipher.getParameters();

    byte[] iv = params.getParameterSpec(IvParameterSpec.class).getIV();
    byte[] cipherText = cipher.doFinal("hello world".getBytes());
这是毫无疑问的。然而,我们还没有发现在Ruby端解密它的神奇序列。如果有人愿意分享如何在ruby(1.9.3)中解密的例子,我们将不胜感激

更新

下面是ruby中目前不起作用的解密代码

d = OpenSSL::Cipher.new("AES-128-CBC")
d.decrypt
key = OpenSSL::PKCS5.pbkdf2_hmac_sha1("password", "8 bytes!", 1024, d.key_len)
d.key = key
d.iv = iv.scan(/../).map{|b|b.hex}.pack('c*')
data = enc.scan(/../).map{|b|b.hex}.pack('c*')
d.update(data) << d.final
d=OpenSSL::Cipher.new(“AES-128-CBC”)
d、 解密
key=OpenSSL::PKCS5.pbkdf2_hmac_sha1(“密码”,“8字节!”,1024,d.key_len)
d、 钥匙
d、 iv=iv.scan(///).map{b | b.hex}.pack('c*'))
data=enc.scan(////).map{| b | b.hex}.pack('c*'))

d、 更新(数据)好的,开始了。不过,您可能需要整理一些参数以适应:

/**
 * Copied shamelessly from org.bouncycastle.crypto.generators.PKCS5S2ParametersGenerator,
 * changed only the hash algorithm.
 * All rights reserved by Bouncy Castle, see their MIT-like permissive license.
 * @author maartenb
 *
 */
public class PKCS5S2_SHA256_ParametersGenerator
    extends PBEParametersGenerator
{

    // NOTE this is the only actual change from PKCS5S2ParametersGenerator
    private Mac    hMac = new HMac(new SHA256Digest());

    /**
     * construct a PKCS5 Scheme 2 Parameters generator.
     */
    public PKCS5S2_SHA256_ParametersGenerator()
    {
    }

    private void F(
        byte[]  P,
        byte[]  S,
        int     c,
        byte[]  iBuf,
        byte[]  out,
        int     outOff)
    {
        byte[]              state = new byte[hMac.getMacSize()];
        CipherParameters    param = new KeyParameter(P);

        hMac.init(param);

        if (S != null)
        {
            hMac.update(S, 0, S.length);
        }

        hMac.update(iBuf, 0, iBuf.length);

        hMac.doFinal(state, 0);

        System.arraycopy(state, 0, out, outOff, state.length);

        if (c == 0)
        {
            throw new IllegalArgumentException("iteration count must be at least 1.");
        }

        for (int count = 1; count < c; count++)
        {
            hMac.init(param);
            hMac.update(state, 0, state.length);
            hMac.doFinal(state, 0);

            for (int j = 0; j != state.length; j++)
            {
                out[outOff + j] ^= state[j];
            }
        }
    }


    private void intToOctet(
        byte[]  buf,
        int     i)
    {
        buf[0] = (byte)(i >>> 24);
        buf[1] = (byte)(i >>> 16);
        buf[2] = (byte)(i >>> 8);
        buf[3] = (byte)i;
    }

    private byte[] generateDerivedKey(
        int dkLen)
    {
        int     hLen = hMac.getMacSize();
        int     l = (dkLen + hLen - 1) / hLen;
        byte[]  iBuf = new byte[4];
        byte[]  out = new byte[l * hLen];

        for (int i = 1; i <= l; i++)
        {
            intToOctet(iBuf, i);

            F(password, salt, iterationCount, iBuf, out, (i - 1) * hLen);
        }

        return out;
    }

    /**
     * Generate a key parameter derived from the password, salt, and iteration
     * count we are currently initialised with.
     *
     * @param keySize the size of the key we want (in bits)
     * @return a KeyParameter object.
     */
    public CipherParameters generateDerivedParameters(
        int keySize)
    {
        keySize = keySize / 8;

        byte[]  dKey = generateDerivedKey(keySize);

        return new KeyParameter(dKey, 0, keySize);
    }

    /**
     * Generate a key with initialisation vector parameter derived from
     * the password, salt, and iteration count we are currently initialised
     * with.
     *
     * @param keySize the size of the key we want (in bits)
     * @param ivSize the size of the iv we want (in bits)
     * @return a ParametersWithIV object.
     */
    public CipherParameters generateDerivedParameters(
        int     keySize,
        int     ivSize)
    {
        keySize = keySize / 8;
        ivSize = ivSize / 8;

        byte[]  dKey = generateDerivedKey(keySize + ivSize);

        return new ParametersWithIV(new KeyParameter(dKey, 0, keySize), dKey, keySize, ivSize);
    }

    /**
     * Generate a key parameter for use with a MAC derived from the password,
     * salt, and iteration count we are currently initialised with.
     *
     * @param keySize the size of the key we want (in bits)
     * @return a KeyParameter object.
     */
    public CipherParameters generateDerivedMacParameters(
        int keySize)
    {
        return generateDerivedParameters(keySize);
    }
}
[编辑]示例用法

        int iterations = 1000; // minimum
        int keySize = 256; // maximum
        final byte[] salt = new byte[8];
        SecureRandom rng = SecureRandom.getInstance("SHA1PRNG");
        rng.nextBytes(salt);
        char[] password = new char[] { 'o', 'w', 'l', 's', 't', 'e', 'a', 'd' };

        // S2 *is* PBKDF2, but the default used only HMAC(SHA-1)
        final PKCS5S2_SHA256_ParametersGenerator gen = new PKCS5S2_SHA256_ParametersGenerator();

        // lets not use String, as we cannot destroy strings, BC to the rescue!
        final byte[] pwBytes = Strings.toUTF8ByteArray(password);

        gen.init(pwBytes, salt, iterations);

        final KeyParameter params1 = (KeyParameter) gen.generateDerivedMacParameters(keySize);

        // use for/next loop for older Java versions, destroy password information in memory
        Arrays.fill(pwBytes, 0, pwBytes.length, (byte) 0);
        Arrays.fill(password, 0, password.length, ' ');
        final KeyParameter keyParam = params1;
        SecretKeySpec secretKey = new SecretKeySpec(keyParam.getKey().clone(), "AES");
[编辑]忘了包括许可证,即使我指向它,但很抱歉将其合法化:

版权所有(c)2000-2011弹跳城堡军团(http://www.bouncycastle.org)

特此免费授予获得本软件及相关文档文件(“软件”)副本的任何人在不受限制的情况下经营本软件的权利,包括但不限于使用、复制、修改、合并、发布、分发、再许可和/或出售本软件副本的权利,并允许向其提供软件的人员在符合以下条件的情况下这样做:

上述版权声明和本许可声明应包含在软件的所有副本或实质部分中


本软件按“原样”提供,无任何明示或暗示的担保,包括但不限于适销性、特定用途适用性和非侵权性担保。在任何情况下,作者或版权持有人均不对任何索赔、损害赔偿或其他责任负责,无论是合同诉讼、侵权诉讼还是其他诉讼,均由本软件或本软件的使用或其他交易引起,或与本软件或本软件的使用或其他交易有关

为什么不使用JRuby呢?然后你可以使用相同的软件包进行解密。这很好,但是这段代码是在Android上运行的(api级别8)-而且我们没有在解密发生的服务器端使用jruby的自由。请展示你已经尝试过的。我可以理解有些东西在没有指示的情况下就失败了,但如果你展示一些Ruby代码,你可能会发现人们更愿意发布答案。此外,这将有助于像我这样懂密码学的Ruby noobs。使用
getBytes()
可能会导致问题。您需要准确地指定两端使用的编码。类似于,
getBytes(“UTF-8”)
@rossum现在我更喜欢Charset.forName(“UTF-8”),因为它消除了选中的异常(无论如何,在符合Java SE的运行时永远不会抛出该异常;UTF-8是一种必需的字符编码)。您需要使用它吗,或者你能自己创造一些解决方案吗?很抱歉反应太晚-是的,我在Sat上花了很长时间。试图整合代码但没有用-如果你有任何见解,我一定会很感激。
        int iterations = 1000; // minimum
        int keySize = 256; // maximum
        final byte[] salt = new byte[8];
        SecureRandom rng = SecureRandom.getInstance("SHA1PRNG");
        rng.nextBytes(salt);
        char[] password = new char[] { 'o', 'w', 'l', 's', 't', 'e', 'a', 'd' };

        // S2 *is* PBKDF2, but the default used only HMAC(SHA-1)
        final PKCS5S2_SHA256_ParametersGenerator gen = new PKCS5S2_SHA256_ParametersGenerator();

        // lets not use String, as we cannot destroy strings, BC to the rescue!
        final byte[] pwBytes = Strings.toUTF8ByteArray(password);

        gen.init(pwBytes, salt, iterations);

        final KeyParameter params1 = (KeyParameter) gen.generateDerivedMacParameters(keySize);

        // use for/next loop for older Java versions, destroy password information in memory
        Arrays.fill(pwBytes, 0, pwBytes.length, (byte) 0);
        Arrays.fill(password, 0, password.length, ' ');
        final KeyParameter keyParam = params1;
        SecretKeySpec secretKey = new SecretKeySpec(keyParam.getKey().clone(), "AES");