Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/dart/3.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
Flutter 颤振中的AES加密无法正常工作_Flutter_Dart_Encryption_Aes - Fatal编程技术网

Flutter 颤振中的AES加密无法正常工作

Flutter 颤振中的AES加密无法正常工作,flutter,dart,encryption,aes,Flutter,Dart,Encryption,Aes,我们正在将一个应用程序从本地Android/iOS移植到Flatter。我们在本机应用程序中使用AES对称加密,它们与我们的设备配合良好 下面是我们试图复制java实现的颤振代码 在这里,我们向设备发送客户端(app)公钥和客户端nonce(随机16位)。设备使用设备公钥、客户端公钥和mac id创建一个加密数据包,并在加密后将其发送到应用程序。我们在应用程序上解密接收到的数据包,并在我们这边创建一个类似的数据包,然后匹配这两个数据包 在我们的例子中,它们在Flutter中都是匹配的(这表明我们

我们正在将一个应用程序从本地Android/iOS移植到Flatter。我们在本机应用程序中使用AES对称加密,它们与我们的设备配合良好

下面是我们试图复制java实现的颤振代码

在这里,我们向设备发送客户端(app)公钥和客户端nonce(随机16位)。设备使用设备公钥、客户端公钥和mac id创建一个加密数据包,并在加密后将其发送到应用程序。我们在应用程序上解密接收到的数据包,并在我们这边创建一个类似的数据包,然后匹配这两个数据包

在我们的例子中,它们在Flutter中都是匹配的(这表明我们已经正确地完成了加密过程)。问题是,在这个过程之后,当我们试图通过加密数据向设备发送下一个命令时,设备无法理解它,并使用垃圾数据进行回复

import'dart:math';
导入“dart:键入的_数据”;
导入“包:asn1lib/asn1lib.dart”;
导入“包:pc_steelcrypt/export.dart”;
进口“包装:钢穴/钢穴.省道”;
导入“package:collection/collection.dart”;
Future startEncryption()异步{
常量字符串SALT_AES_KEY='AES-KEY';
常量字符串SALT_AES_IV='AES-IV';
final Uint8List serverResponse=wait sendunecryptedCommand(getFirstMessagePayload());
最终Uint8List macId=getMacId(serverResponse);
最终Uint8List saltNonceServer=getSaltNounceServer(serverResponse);
最终Uint8List serverCertificate=getCertificate(serverResponse);
//解析服务器证书
最终ASN1Parser p=ASN1Parser(服务器证书);
最终ASN1序列signedCert=p.nextObject()作为ASN1序列;
最终ASN1序列证书=作为ASN1序列的已签名证书元素[0];
最终ASN1序列pubKeyElement=cert.elements[6]作为ASN1序列;
最终ASN1BitString pubKeyBits=pubKeyElement。元素[1]为ASN1BitString;
打印('publikeybits:$publikeybits');
//TODO:也需要对证书进行身份验证
//客户端密钥生成:
最终ECCurve_secp256r1 secp256r1=ECCurve_secp256r1();
最终ECQ点=
secp256r1.curve.decodePoint(publikeybits.contentBytes().toList());
最终ECPublicKey服务器PublicKey=ECPublicKey(Q,secp256r1);
最终ECCurve_secp256r1 _nistp256=ECCurve_secp256r1();
最终ECKeyGenerator参数ECKeyGenerator参数=
ECKeyGeneratorParameters(_nistp256);
最终SecureRandom sr=getSecureRandom();
最终参数SwithRandom参数SwithRandom=
参数Swithrandom(ECKeyGenerator参数,sr);
最终ECKeyGenerator ECKeyGenerator=ECKeyGenerator();
ecKeyGenerator.init(参数swithrandom);
final _clientKeyPair=ecKeyGenerator.generateKeyPair();
最终SecureRandom sr2=getSecureRandom();
最终Uint8List clientNonce=sr2.nextBytes(16);
final clientPubKeyRaw=getCertificateRaw(_clientKeyPair.publicKey作为ECPublicKey);
最终Uint8List消息=Uint8List(80);
copyRange(msg,0,clientPubKeyRaw,0,64);
copyRange(msg,64,clientNonce,0,16);
最终Uint8List signedData=等待发送未加密命令(msg);
final secret=serverPublicKey.Q*(_clientKeyPair.privateKey作为ECPrivateKey).d;
Uint8List sharedSecret=secret.getEncoded();
if(sharedSecret.length==33){
sharedSecret=sharedSecret.子列表(1);
}
final Uint8List aesKey=生成128位密钥forble(共享秘密、Uint8List.fromList(SALT_AES_KEY.codeUnits)、saltnoneserver、clientNonce);
final Uint8List aesIv=生成128位密钥forble(共享秘密、Uint8List.fromList(SALT_AES_IV.codeUnits)、saltnoneserver、clientNonce);
最终AesCryptRaw AesCryptRaw=AesCryptRaw(填充:PaddingAES.none,键:aesKey);
最终UINT8列表serverPubKeyRaw=getCertificateRaw(serverPubKeyRaw);
final int clientToBeSignedLength=serverPubKeyRaw.length+clientPubKeyRaw.length+macId.length;
最终Uint8List clientToBeSigned=Uint8List(clientToBeSignedLength);
copyRange(clientToBeSigned,0,serverPubKeyRaw,0,serverPubKeyRaw.length);
copyRange(clientToBeSigned,serverPubKeyRaw.length,clientPubKeyRaw,0,clientPubKeyRaw.length);
copyRange(clientToBeSigned,serverPubKeyRaw.length+clientPubKeyRaw.length,macId,0,macId.length);
最终摘要md=SHA256Digest();
md.update(clientToBeSigned,0,clientToBeSigned.length);
最终Uint8List clientHash=Uint8List(md.digestSize);
md.doFinal(clientHash,0);
最终Uint8List serverHash=aesnypter.ctr.decrypt(enc:signedData,iv:aesIv);
最终函数deepEq=deepCollectionQuality()。等于;
最终bool结果=作为bool的deepEq(serverHash,clientHash);
如果(结果){
打印(“加密成功”);
//第一次向设备发送加密命令。使用AES加密程序加密
sendEncryptedCommand(aesEncrypter,Uint8List.fromList([2,2]);
}否则{
打印(“加密失败”);
}
}
UINT8列表getCertificateRaw(ECPublicKey publicKey){
最终publicKeyRaw=UINT8列表(64);
Uint8List result=publicKey.Q.getEncoded(false);
result=result.length==65?result.sublist(1):结果;
copyRange(publicKeyRaw,0,result,0,result.length);
返回publicKeyRaw;
}
UINT8列表生成128位密钥表(UINT8列表共享密钥,
Uint8List salt、Uint8List serverNonce、Uint8List clientNonce){
最终消化器=SHA256Digest();
消化池更新(sharedSecret,0,sharedSecret.length);
蒸煮器。更新(盐,0,盐。长度);
更新(clientNonce,0,clientNonce.length);
更新(serverNonce,0,serverNonce.length);
最终Uint8List EXPUFFER=Uint8List(消化池.消化池尺寸);
蒸煮器。最终(0);

if(exputffer.length)不清楚您在哪里遇到了问题。您说有些东西匹配,但其他东西不匹配。您能否给出一个简单的示例,说明一些java代码和dart代码尝试执行相同的操作并返回不同的结果(使用测试向量)?@RichardHeap我对这个加密过程不是很确定,但据我所知,我
class EncryptionKeyPair {
private static ECParameterSpec nistp256 = new ECParameterSpec(
        new EllipticCurve(
                new ECFieldFp(new BigInteger
                        ("FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF",
                                16)),
                new BigInteger
                        ("FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFC",
                                16),
                new BigInteger
                        ("5ac635d8aa3a93e7bb2ebdb7676RE86bc651d06b45c54c0f63bce3c3e27d2604b",
                                16)),
        new ECPoint(new BigInteger
                ("6B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A18655D898C296", 16),
                new BigInteger
                        ("3DE342FAFE2A7F9B4AA6EB4A7C0F9E162BCE33576B315ECECBB6406837BF51F5",
                                16)),
        new BigInteger("FFFFFFFF00000000FFFFFFFFFFFFFFFFECE4FAAFA7179E94F4A9CAB2FC432543", 16),
        1);
public ECPrivateKey mPrivate;
public ECPublicKey mPublic;

public void generateKey() throws IOException {
    KeyPairGenerator kpg;
    try {
        kpg = KeyPairGenerator.getInstance("EC");
        kpg.initialize(nistp256);
        KeyPair pair = kpg.generateKeyPair();
        mPrivate = (ECPrivateKey) pair.getPrivate();
        mPublic = (ECPublicKey) pair.getPublic();
    } catch (NoSuchAlgorithmException e) {
        throw new IOException("No DH keypair generator", e);
    } catch (InvalidAlgorithmParameterException e) {
        throw new IOException("Invalid DH parameters", e);
    }
}
}
KeyAgreement ka;
    try {
        ka = KeyAgreement.getInstance("ECDH");
        ka.init((ECPrivateKey) keyPair.mPrivate);
        ka.doPhase(certificate.getPublicKey(), true);
        return ka.generateSecret();
    } catch (Exception e) {
        e.printStackTrace();
    }