用C#在Windows Phone 8.1上加密,用Java解密

用C#在Windows Phone 8.1上加密,用Java解密,java,c#,encryption,windows-phone-8.1,Java,C#,Encryption,Windows Phone 8.1,当Java代码用于服务时,C#位于客户端。Windows phone加密数据,而Java使用相同的对称密钥解密数据 下面是我的C#加密方法 公共静态字符串加密测试(字符串数据、字符串密码) { SymmetricKeyAlgorithmProvider SAP=SymmetricKeyAlgorithmProvider.OpenAlgorithm(SymmetricAlgorithmNames.AesEcbPkcs7); 加密密钥AES; HashAlgorithmProvider HAP=Ha

当Java代码用于服务时,C#位于客户端。Windows phone加密数据,而Java使用相同的对称密钥解密数据

下面是我的C#加密方法

公共静态字符串加密测试(字符串数据、字符串密码)
{
SymmetricKeyAlgorithmProvider SAP=SymmetricKeyAlgorithmProvider.OpenAlgorithm(SymmetricAlgorithmNames.AesEcbPkcs7);
加密密钥AES;
HashAlgorithmProvider HAP=HashAlgorithmProvider.OpenAlgorithm(HashAlgorithmNames.Sha512);
Windows.Security.Cryptography.Core.CryptographyHash哈希_AES=HAP.CreateHash();
字符串加密;
尝试
{
字节[]散列=新字节[16];
Hash_AES.Append(cryptographicsbuffer.CreateFromByteArray(System.Convert.FromBase64String(密码));
字节[]温度;
CryptographicBuffer.CopyToByteArray(Hash_AES.GetValueAndReset(),out temp);
复制(temp,0,hash,0,16);
复制(临时,0,散列,15,16);
AES=SAP.CreateSymmetricKey(CryptographicBuffer.CreateFromByteArray(哈希));
IBuffer Buffer=cryptographicsbuffer.CreateFromByteArray(Encoding.UTF8.GetBytes(数据));
encrypted=CryptographicBuffer.EncodeToBase64String(CryptographicEngine.Encrypt(AES,Buffer,null));
返回加密;
}
抓住
{
返回“加密错误”;
}
}
下面是我的Java解密类

private secretKey spec secretKey;
public void setKey(){
skey=“mykey”;
MessageDigest-sha=null;
试一试{
key=skey.getBytes(“UTF-8”);
logger.debug(“Key length==>”+Key.length);
sha=MessageDigest.getInstance(“sha-512”);
key=sha.digest(key);
key=array.copyOf(key,16);//仅使用前128位
secretKey=新的SecretKeySpec(key,“AES”);
}捕获(无算法异常){
e、 printStackTrace();
}捕获(不支持的编码异常e){
e、 printStackTrace();
}
}
公共字符串解密(字符串strotdecrypt){
密码=空;
试一试{
cipher=cipher.getInstance(“AES/ECB/PKCS5PADDING”);
cipher.init(cipher.DECRYPT_模式,this.secretKey);
setDecryptedString(新字符串)(cipher.doFinal(Base64
.decodeBase64(strToDecrypt));
}捕获(例外e){
System.out.println(“解密时出错:+e.toString());
}
返回null;
}

密钥生成未完成。出于某种原因,您的C#代码使用以下代码将密钥的最后一个字节设置为与第一个字节相同的值:

Array.Copy(temp, 0, hash, 0, 16);
Array.Copy(temp, 0, hash, 15, 16);
(据我所知,这可能会引发一些异常,因为如果从索引15开始,则无法将16字节复制到16字节数组
散列中。)

在Java中也可以做同样的(不好的)事情

public void setKey() {
    skey = "mykey";
    MessageDigest sha = null;
    try {
        key = skey.getBytes("UTF-8");
        logger.debug("Key length ====> " + key.length);
        sha = MessageDigest.getInstance("SHA-512");
        key = sha.digest(key);
        key = Arrays.copyOf(key, 16); // use only first 128 bit
        key[15] = key[0]; // added

        secretKey = new SecretKeySpec(key, "AES");
    } catch (NoSuchAlgorithmException e) {
        e.printStackTrace();
    } catch (UnsupportedEncodingException e) {
        e.printStackTrace();
    }
}

需要考虑的事项:

  • ECB模式不提供语义安全性,不应使用该模式。对于同一密钥下的每个加密,至少使用带有随机IV的CBC模式
  • 密码应进行多次哈希运算。单个哈希运算可使攻击者很容易强行输入密码,因为这是一种快速操作。您应该使用基于密码的加密和强密钥派生函数,如PBKDF2(超过100000次迭代)、scrypt或bcrypt。别忘了用随机的盐
  • 验证您的密文。您可能希望检测传输过程中对密文的(恶意)操作。这可以通过认证模式(如GCM或EAX)来实现,也可以通过在密文上运行MAC算法来实现。强MAC是HMAC-SHA256

您有问题吗?它有效吗?如果没有,您是否收到任何错误?如果您加密的数据块超过1个,请不要使用ECB。一个使用pkcs5,另一个使用PKCS7。您为什么创建新帐户?你可以用你的旧的。由于您提出了另一个问题,您可以删除(使用您的其他帐户)。另见: