ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

c# – java和.net中的加密结果不一样

2019-10-05 13:03:41  阅读:241  来源: 互联网

标签:java encryption aes md5 c-2


我的.net项目中有一个方法来加密密码

public string Encrypt(string plainText)
{
    string PassPhrase = "#$^&*!@!$";
    string SaltValue = "R@j@}{BAe";
    int PasswordIterations = Convert.ToInt32(textBox5.Text); //amend to match java encryption iteration
    string InitVector = "@1B2c3D4e5F6g7H8";
    int KeySize = 256; //amend to match java encryption key size

    byte[] initVectorBytes = Encoding.ASCII.GetBytes(InitVector);
    byte[] saltValueBytes = Encoding.ASCII.GetBytes(SaltValue);

    byte[] plainTextBytes = Encoding.UTF8.GetBytes(plainText);

    PasswordDeriveBytes password= new PasswordDeriveBytes(
        PassPhrase,
        saltValueBytes,
        "MD5",
        PasswordIterations);

    byte[] keyBytes = password.GetBytes(KeySize / 8);
    RijndaelManaged symmetricKey = new RijndaelManaged();
    symmetricKey.Mode = CipherMode.CBC;

    ICryptoTransform encryptor = symmetricKey.CreateEncryptor(
                                                     keyBytes,
                                                     initVectorBytes);
    MemoryStream memoryStream = new MemoryStream();

    CryptoStream cryptoStream = new CryptoStream(memoryStream,
                                                 encryptor,
                                                 CryptoStreamMode.Write);

    cryptoStream.Write(plainTextBytes, 0, plainTextBytes.Length);
    cryptoStream.FlushFinalBlock();
    byte[] cipherTextBytes = memoryStream.ToArray();

    memoryStream.Close();
    cryptoStream.Close();

    string cipherText = Convert.ToBase64String(cipherTextBytes);

    return cipherText;
}

我的任务是将此方法转换为java但在java中我得不到与.Net版本相同的结果

我的java代码是

package com.andc.billing.pdc.security;

import java.io.UnsupportedEncodingException;
import java.security.InvalidAlgorithmParameterException;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.InvalidParameterSpecException;

import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.PBEKeySpec;
import javax.crypto.spec.SecretKeySpec;
import javax.management.openmbean.InvalidKeyException;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

public class PasswordCrypto {

    private static final String password = "#$^&*!@!$";
    private static String initializationVector = "@1B2c3D4e5F6g7H8";
    private static String salt = "R@j@}{BAe";
    private static int pswdIterations = 2;
    private static int keySize = 128;
    private static final Log log = LogFactory.getLog(PasswordCrypto.class);

    public static String encrypt(String plainText) throws 
        NoSuchAlgorithmException, 
        InvalidKeySpecException, 
        NoSuchPaddingException, 
        InvalidParameterSpecException, 
        IllegalBlockSizeException, 
        BadPaddingException, 
        UnsupportedEncodingException, 
        InvalidKeyException, 
        InvalidAlgorithmParameterException, java.security.InvalidKeyException, NoSuchProviderException 
    {   
        byte[] saltBytes = salt.getBytes("ASCII");//"UTF-8");
        byte[] ivBytes = initializationVector.getBytes("ASCII");//"UTF-8");

        // Derive the key, given password and salt.
        SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1");//PBEWithMD5AndDES");
        PBEKeySpec spec = new PBEKeySpec(
                password.toCharArray(), 
                saltBytes, 
                pswdIterations, 
                keySize
        );

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


        Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); //Cipher.getInstance("AES/CBC/PKCSPadding"
        cipher.init(Cipher.ENCRYPT_MODE, secret, new IvParameterSpec(ivBytes));

        byte[] encryptedTextBytes = cipher.doFinal(plainText.getBytes("ASCII"));//UTF-8"));
        String str=new org.apache.commons.codec.binary.Base64().encodeAsString(encryptedTextBytes);
        log.info(str);
        return str;
    }
}

加密“1”的.net结果是:

7mPh3/E/olBGbFpoA18oqw==

而java是

7RPk77AIKAhOttNLW4e5yQ==

你能帮我解决一下这个问题吗?

解决方法:

我注意到的第一件事是你使用的算法是不同的,在.Net中它是PBKDF1的扩展,在java中它是PBKDF2,PBKDF2取代了PBKDF1.

在.net中,您使用的是“使用PBKDF1算法扩展从密码中获取密钥”的the PasswordDeriveBytes class.

我还注意到,密码迭代在Java中硬编码为2,来自.Net中的文本框…确保它们是相同的.

纠正这一点,让我们知道结果.

更新:对于.net中的PBKDF2,请使用Rfc2898DeriveBytes类.

对于一些非常好的相关信息have a read of this page

编辑:This link should be helpful,如果你可以使用Chilkat library

它是1和2之间的复杂差异,1只应该做多达20个字节,MS已经建立了一个允许更多的扩展,以下代码应该更准确地重新定义.net输出. Taken from here.

import org.bouncycastle.crypto.CipherParameters;
import org.bouncycastle.crypto.Digest;
import org.bouncycastle.crypto.digests.SHA1Digest;
import org.bouncycastle.crypto.generators.PKCS5S1ParametersGenerator;
import org.bouncycastle.crypto.params.KeyParameter;
import org.bouncycastle.util.encoders.Hex;


public class PKCS5Test
{
    /**
     * @param args
     */
    public static void main(String[] args) throws Exception
    {
        byte[] password = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 };
        byte[] salt = PKCS5S1ParametersGenerator.PKCS5PasswordToBytes("MyTesting".toCharArray());

        PKCS5S1ParametersGenerator generator = new PasswordDeriveBytes(new SHA1Digest());
        generator.init(password, salt, 100);

        byte[] key = ((KeyParameter)generator.generateDerivedParameters(512)).getKey();
        System.out.println( "64 " + new String(Hex.encode(key)).toUpperCase() );
    }

    static class PasswordDeriveBytes extends PKCS5S1ParametersGenerator
    {
        private final Digest d;

        private byte[] output = null;

        public PasswordDeriveBytes(Digest d)
        {
            super(d);

            this.d = d;
        }

        public CipherParameters generateDerivedParameters(int keySize)
        {
            keySize = keySize / 8;

            byte[] result = new byte[keySize];
            int done = 0;
            int count = 0;
            byte[] b = null;

            while (done < result.length)
            {
                if (b == null)
                {
                    b = generateInitialKey();
                }
                else if (++count < 1000)
                {
                    b = generateExtendedKey(++count);
                }
                else
                {
                    throw new RuntimeException("Exceeded limit");
                }

                int use = Math.min(b.length, result.length - done);
                System.arraycopy(b, 0, result, done, use);
                done += use;
            }

            return new KeyParameter(result);
        }

        private byte[] generateOutput()
        {
            byte[] digestBytes = new byte[d.getDigestSize()];

            d.update(password, 0, password.length);
            d.update(salt, 0, salt.length);
            d.doFinal(digestBytes, 0);

            for (int i = 1; i < (iterationCount - 1); i++)
            {
                d.update(digestBytes, 0, digestBytes.length);
                d.doFinal(digestBytes, 0);
            }

            return digestBytes;
        }

        private byte[] generateInitialKey()
        {
            output = generateOutput();
            d.update(output, 0, output.length);

            byte[] digestBytes = new byte[d.getDigestSize()];
            d.doFinal(digestBytes, 0);
            return digestBytes;
        }

        private byte[] generateExtendedKey(int count)
        {
            byte[] prefix = Integer.toString(count).getBytes();
            d.update(prefix, 0, prefix.length);
            d.update(output, 0, output.length);

            byte[] digestBytes = new byte[d.getDigestSize()];
            d.doFinal(digestBytes, 0);

            //System.err.println( "X: " + new String(Hex.encode(digestBytes)).toUpperCase() );
            return digestBytes;
        }
    }
} 

标签:java,encryption,aes,md5,c-2
来源: https://codeday.me/bug/20191005/1856178.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有