代码之家  ›  专栏  ›  技术社区  ›  KisnardOnline

AdMob-预缓存异常-服务器端验证SSV不工作

  •  0
  • KisnardOnline  · 技术社区  · 2 年前

    我的Android应用程序是MMORPG,所以它连接到我的服务器。出于某种原因,这打破了AdMob的SSV。广告显示良好(测试和真实),但从未接收到服务器端验证回调。这让我发疯了——谢谢你的帮助。

    以下是我在logcat中看到的警告信息:

    Precache exception
        hi: javax.net.ssl.SSLProtocolException: Read error: ssl=0x77c5e4c0b798: Failure in SSL library, usually a protocol error
        error:1e000065:Cipher functions:OPENSSL_internal:BAD_DECRYPT (external/boringssl/src/crypto/fipsmodule/cipher/e_aes.c:1095 0x77c538ad22dc:0x00000000)
        error:1000008b:SSL routines:OPENSSL_internal:DECRYPTION_FAILED_OR_BAD_RECORD_MAC (external/boringssl/src/ssl/tls_record.cc:298 0x77c538ad22dc:0x00000000)
            at hd.a(:com.google.android.gms.policy_ads_fdr_dynamite@[email protected]:6)
            at hq.a(:com.google.android.gms.policy_ads_fdr_dynamite@[email protected]:0)
            at xv.b(:com.google.android.gms.policy_ads_fdr_dynamite@[email protected]:2)
            at xv.a(:com.google.android.gms.policy_ads_fdr_dynamite@[email protected]:2)
            at tx.t(:com.google.android.gms.policy_ads_fdr_dynamite@[email protected]:4)
            at yr.a(:com.google.android.gms.policy_ads_fdr_dynamite@[email protected]:0)
            at zt.m(:com.google.android.gms.policy_ads_fdr_dynamite@[email protected]:2)
            at zt.l(:com.google.android.gms.policy_ads_fdr_dynamite@[email protected]:31)
            at zt.j(:com.google.android.gms.policy_ads_fdr_dynamite@[email protected]:39)
            at zt.d(:com.google.android.gms.policy_ads_fdr_dynamite@[email protected]:30)
            at wc.run(:com.google.android.gms.policy_ads_fdr_dynamite@[email protected]:43)
            at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1137)
            at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:637)
            at java.lang.Thread.run(Thread.java:1012)
        Caused by: javax.net.ssl.SSLProtocolException: Read error: ssl=0x77c5e4c0b798: Failure in SSL library, usually a protocol error
        error:1e000065:Cipher functions:OPENSSL_internal:BAD_DECRYPT (external/boringssl/src/crypto/fipsmodule/cipher/e_aes.c:1095 0x77c538ad22dc:0x00000000)
        error:1000008b:SSL routines:OPENSSL_internal:DECRYPTION_FAILED_OR_BAD_RECORD_MAC (external/boringssl/src/ssl/tls_record.cc:298 0x77c538ad22dc:0x00000000)
            at com.android.org.conscrypt.NativeCrypto.ENGINE_SSL_read_direct(Native Method)
            at com.android.org.conscrypt.NativeSsl.readDirectByteBuffer(NativeSsl.java:569)
            at com.android.org.conscrypt.ConscryptEngine.readPlaintextDataDirect(ConscryptEngine.java:1095)
            at com.android.org.conscrypt.ConscryptEngine.readPlaintextData(ConscryptEngine.java:1079)
            at com.android.org.conscrypt.ConscryptEngine.unwrap(ConscryptEngine.java:876)
            at com.android.org.conscrypt.ConscryptEngine.unwrap(ConscryptEngine.java:747)
            at com.android.org.conscrypt.ConscryptEngine.unwrap(ConscryptEngine.java:712)
            at com.android.org.conscrypt.ConscryptEngineSocket$SSLInputStream.processDataFromSocket(ConscryptEngineSocket.java:858)
            at com.android.org.conscrypt.ConscryptEngineSocket$SSLInputStream.readUntilDataAvailable(ConscryptEngineSocket.java:824)
            at com.android.org.conscrypt.ConscryptEngineSocket$SSLInputStream.read(ConscryptEngineSocket.java:797)
            at com.android.okhttp.okio.Okio$2.read(Okio.java:138)
            at com.android.okhttp.okio.AsyncTimeout$2.read(AsyncTimeout.java:213)
            at com.android.okhttp.okio.RealBufferedSource.read(RealBufferedSource.java:51)
            at com.android.okhttp.internal.http.Http1xStream$FixedLengthSource.read(Http1xStream.java:395)
            at com.android.okhttp.okio.RealBufferedSource$1.read(RealBufferedSource.java:372)
            at hd.a(:com.google.android.gms.policy_ads_fdr_dynamite@23[email protected]:3)
            ... 13 more
    

    以下是我的客户端SSL连接代码:

    //load your key store as a stream and initialize a KeyStore
    KeyStore trustStore = KeyStore.getInstance(KeyStore.getDefaultType());
    
    //if your store is password protected then declare it (it can be null however)
    String tsName = "res/gamedata/truststore-bks";
    char[] trustPassword = "REDACTED".toCharArray();
    
    //load the stream to your store
    trustStore.load(MyCommandReceiver.GetActiveActivity().getAssets().open(tsName), trustPassword);
    
    //initialize a trust manager factory with the trusted store
    TrustManagerFactory trustFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
    trustFactory.init(trustStore);
    
    //get the trust managers from the factory
    TrustManager[] trustManagers = trustFactory.getTrustManagers();
    
    //initialize an ssl context to use these managers and set as default
    //SSLContext sslContext = SSLContext.getInstance("SSL");
    SSLContext sslContext = SSLContext.getInstance("TLSv1.3");
    sslContext.init(null, trustManagers, null);
    //SSLContext.setDefault(sslContext); //this was breaking admob ads from loading - and likely other stuff too
    
    //create sslfactory from the ssl context
    SSLSocketFactory factory = sslContext.getSocketFactory();
    
    final int connectTimeout = 6 * 1000; //6 seconds to connect
    if (GameActivity.isPROD) {
        //https://stackoverflow.com/questions/5715751/ssl-socket-connect-timeout
        //GameActivity.sC = (SSLSocket) SSLSocketFactory.getDefault().createSocket(); //the way code wanted me to do it
        GameActivity.sC = (SSLSocket) factory.createSocket();
        GameActivity.sC.setSoTimeout(connectTimeout);
        GameActivity.sC.connect(new InetSocketAddress(GameActivity.PROD_IP, GameActivity.PROD_PORT), connectTimeout);
    } else {
        GameActivity.ShowLongToast("===DEV SERVER===");
        //https://stackoverflow.com/questions/5715751/ssl-socket-connect-timeout
        //GameActivity.sC = (SSLSocket) SSLSocketFactory.getDefault().createSocket(); //the way code wanted me to do it
        GameActivity.sC = (SSLSocket) factory.createSocket();
        GameActivity.sC.setSoTimeout(connectTimeout);
        GameActivity.sC.connect(new InetSocketAddress(GameActivity.DEV_IP, GameActivity.PROD_PORT), connectTimeout);
    }
    
    //GameActivity.sC.setEnabledProtocols(new String[]{"SSLv3", "TLSv1", "TLSv1.1", "TLSv1.2"});
    //GameActivity.sC.setEnabledProtocols(new String[]{"TLSv1.2", "TLSv1.3"});
    GameActivity.sC.setEnabledProtocols(new String[]{"TLSv1.3"});
    //even tried with line above commented out
    
    GameActivity.LoggerWrite("i", TAG, "LoginActivity:connectToServer: ------SUPPORTED CIPHER SUITES------");
    GameActivity.LoggerWrite("i", TAG, Arrays.toString(factory.getSupportedCipherSuites()));
    GameActivity.LoggerWrite("i", TAG, "LoginActivity:connectToServer:------SOCKET INFO------");
    printSocketInfo(GameActivity.sC);
    GameActivity.sC.setSoTimeout(0);
    GameActivity.LoggerWrite("i", TAG, "LoginActivity:connectToServer:------START HANDSHAKE------");
    GameActivity.sC.startHandshake();
    
    GameActivity.sC.addHandshakeCompletedListener(new HandshakeCompletedListener() {
        @Override
        public void handshakeCompleted(HandshakeCompletedEvent arg0) {
            GameActivity.LoggerWrite("i", TAG, "LoginActivity:connectToServer:------HANDSHAKE-COMPLETED-LISTENER - START------");
            GameActivity.LoggerWrite("i", TAG, "LoginActivity:connectToServer:Cipher suite: " + arg0.getCipherSuite());
    
            GameActivity.LoggerWrite("i", TAG, "LoginActivity:connectToServer:Local Principal: " + arg0.getLocalPrincipal());
    
            Certificate[] peerCertificates = null;
            try {
                peerCertificates = arg0.getPeerCertificates();
                for (Certificate s : peerCertificates) {
                    GameActivity.LoggerWrite("i", TAG, "LoginActivity:connectToServer:Peer Certificate(public key): " + s.getPublicKey());
                }
            } catch (SSLPeerUnverifiedException e) {
                GameActivity.LoggerWrite("e", TAG, "LoginActivity:connectToServer:arg0.getPeerCertificates()" + e);
            }
    
            try {
                GameActivity.LoggerWrite("i", TAG, "LoginActivity:connectToServer:Peer Principal: " + arg0.getPeerPrincipal());
            } catch (SSLPeerUnverifiedException e) {
                GameActivity.LoggerWrite("e", TAG, "LoginActivity:connectToServer:arg0.getPeerPrincipal()" + e);
            }
            GameActivity.LoggerWrite("i", TAG, "LoginActivity:connectToServer:Session: " + arg0.getSession());
            GameActivity.LoggerWrite("i", TAG, "LoginActivity:connectToServer:Socket: " + arg0.getSocket());
            GameActivity.LoggerWrite("i", TAG, "LoginActivity:connectToServer:Source: " + arg0.getSource());
            GameActivity.LoggerWrite("i", TAG, "LoginActivity:connectToServer:------HANDSHAKE-COMPLETED-LISTENER - END------");
    
    //                        connectedToServer = true; //so subsequent clicks to Login don't make new connections
        }
    });
    
    GameActivity.LoggerWrite("i", TAG, "LoginActivity:connectToServer:------START DataStreams - START------");
    GameActivity.commandIn = new DataInputStream(GameActivity.sC.getInputStream()); //create input-stream for a command socket
    GameActivity.commandOut = new DataOutputStream(GameActivity.sC.getOutputStream()); //create output-stream for a command socket
    GameActivity.LoggerWrite("i", TAG, "LoginActivity:connectToServer:------START DataStreams - END------");
    
    //creating a thread for receiving commands
    MyCommandReceiver.GetActiveActivity().runOnUiThread(new Runnable() {
        @Override
        public void run() {
            GameActivity.commandReceiver = new MyCommandReceiver();
            GameActivity.commandReceiverThread = new Thread(null, GameActivity.commandReceiver, "commandReceiver-" + ""); //characterName
            GameActivity.commandReceiverThread.setDaemon(true);
            GameActivity.commandReceiverThread.start();
        }
    });
    
    0 回复  |  直到 2 年前
    推荐文章