【问题标题】:KeyStore.load() fails with "Invalid keystore format"KeyStore.load() 因“无效的密钥库格式”而失败
【发布时间】:2019-08-18 01:53:10
【问题描述】:

在执行 keystore.load() 方法时,以下代码每次都会失败,并出现“无效的密钥库格式”的 IOException。该文件已成功从 .jar 文件加载。在 Windows 10 专业版上使用 Java 1.8。 Maven用于编译和组装jar文件,然后一起war并作为war文件部署到JBOSS服务器。我也尝试使用 .getInstance 和 getDefault() 并出现相同的错误。

InputStream stream;
stream = Thread.currentThread().getContextClassLoader()
    .getResourceAsStream("cacerts.jks");
if (stream == null) {
    stream = CustomTrustManager.class.getClassLoader()
        .getResourceAsStream("cacerts.jks");
}
if(stream == null) {
    Log.error("Unable to load cacerts.jks. This is needed to make HTTPS connections to internal servers.");
    throw new NotFoundException();
}

KeyStore myTrustStore = KeyStore.getInstance("JKS");
myTrustStore.load(stream, "xxxxx".toCharArray());

“cacerts.jks”文件是使用以下命令从自签名服务器证书“server1.crt”文件生成的:

keytool -v -import -alias devserver -file server1.crt -keystore cacerts.jks

这成功完成并命令:

keytool -list -keystore cacerts.jks
Keystore type: JKS
Keystore provider: SUN

Your keystore contains 1 entry

devserver, Aug 15, 2019, trustedCertEntry,
Certificate fingerprint (SHA1): F6:7F:C9:95:0E:B8:59:07:24:23:67:93:43:B2:C9:AA:CD:5B:AF:68

显示密钥库文件没有问题。我扫描了许多 StackOverflow 文章,但没有一个指向该问题的解决方案。在调试模式下,一旦加载资源,InputStream 将具有以下格式。我假设 ZipFile 类型从 .jar 文件加载是正常的。

了解有关如何成功加载密钥库文件的任何见解。谢谢

下面的堆栈跟踪:

2019-08-18 17:00:53,038 ERROR service.CustomTrustManager (CustomTrustManager.java:59) [default task-2] - KeyStore failed to laod
java.io.IOException: Invalid keystore format
at sun.security.provider.JavaKeyStore.engineLoad(JavaKeyStore.java:658) ~[?:1.8.0_161]
at sun.security.provider.JavaKeyStore$JKS.engineLoad(JavaKeyStore.java:56) ~[?:1.8.0_161]
at sun.security.provider.KeyStoreDelegator.engineLoad(KeyStoreDelegator.java:224) ~[?:1.8.0_161]
at sun.security.provider.JavaKeyStore$DualFormatJKS.engineLoad(JavaKeyStore.java:70) ~[?:1.8.0_161]
at java.security.KeyStore.load(KeyStore.java:1445) ~[?:1.8.0_161]
at cinfin.thirdparty.service.CustomTrustManager.<init>(CustomTrustManager.java:57) [ThirdPartyWSCore-1.13.0.jar:1.13.0]
at cinfin.thirdparty.riskmeter.service.RiskMeterClientService.configureSSL(RiskMeterClientService.java:125) [ThirdPartyWSRiskMeter-1.0.0.jar:?]
at cinfin.thirdparty.riskmeter.service.RiskMeterClientService.getHttpClient(RiskMeterClientService.java:103) [ThirdPartyWSRiskMeter-1.0.0.jar:?]
at cinfin.thirdparty.riskmeter.service.RiskMeterClientService.getRiskMeterData(RiskMeterClientService.java:87) [ThirdPartyWSRiskMeter-1.0.0.jar:?]
at cinfin.thirdparty.riskmeter.bo.RiskMeterBo.getRiskMeterData(RiskMeterBo.java:50) [ThirdPartyWSRiskMeter-1.0.0.jar:?]
at cinfin.thirdparty.riskmeter.ws.RiskMeterService.getRiskMeterData(RiskMeterService.java:18) [ThirdPartyWSRiskMeter-1.0.0.jar:?]
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[?:1.8.0_161]
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[?:1.8.0_161]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[?:1.8.0_161]
at java.lang.reflect.Method.invoke(Method.java:498) ~[?:1.8.0_161]
at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:333) [spring-aop-4.3.24.RELEASE.jar:4.3.24.RELEASE]
at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:190) [spring-aop-4.3.24.RELEASE.jar:4.3.24.RELEASE]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:157) [spring-aop-4.3.24.RELEASE.jar:4.3.24.RELEASE]
at org.springframework.aop.aspectj.MethodInvocationProceedingJoinPoint.proceed(MethodInvocationProceedingJoinPoint.java:84) [spring-aop-4.3.24.RELEASE.jar:4.3.24.RELEASE]
at cinfin.thirdparty.metering.bo.MeteringAspectImpl.performVendorCall(MeteringAspectImpl.java:64) [ThirdPartyWSCore-1.13.0.jar:1.13.0]
at cinfin.thirdparty.metering.bo.MeteringAspectImpl.aroundMeteredAnnotationAdvice(MeteringAspectImpl.java:33) [ThirdPartyWSCore-1.13.0.jar:1.13.0]
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[?:1.8.0_161]
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[?:1.8.0_161]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[?:1.8.0_161]
at java.lang.reflect.Method.invoke(Method.java:498) ~[?:1.8.0_161]
at org.springframework.aop.aspectj.AbstractAspectJAdvice.invokeAdviceMethodWithGivenArgs(AbstractAspectJAdvice.java:627) [spring-aop-4.3.24.RELEASE.jar:4.3.24.RELEASE]
at org.springframework.aop.aspectj.AbstractAspectJAdvice.invokeAdviceMethod(AbstractAspectJAdvice.java:616) [spring-aop-4.3.24.RELEASE.jar:4.3.24.RELEASE]
at org.springframework.aop.aspectj.AspectJAroundAdvice.invoke(AspectJAroundAdvice.java:70) [spring-aop-4.3.24.RELEASE.jar:4.3.24.RELEASE]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:168) [spring-aop-4.3.24.RELEASE.jar:4.3.24.RELEASE]
at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:92) [spring-aop-4.3.24.RELEASE.jar:4.3.24.RELEASE]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179) [spring-aop-4.3.24.RELEASE.jar:4.3.24.RELEASE]
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:213) [spring-aop-4.3.24.RELEASE.jar:4.3.24.RELEASE]
at com.sun.proxy.$Proxy206.getRiskMeterData(Unknown Source) [?:?]
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[?:1.8.0_161]
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[?:1.8.0_161]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[?:1.8.0_161]
at java.lang.reflect.Method.invoke(Method.java:498) ~[?:1.8.0_161]
at org.apache.cxf.service.invoker.AbstractInvoker.performInvocation(AbstractInvoker.java:180) [cxf-core-3.1.10.jar:3.1.10]
at org.apache.cxf.service.invoker.AbstractInvoker.invoke(AbstractInvoker.java:96) [cxf-core-3.1.10.jar:3.1.10]
at org.apache.cxf.jaxrs.JAXRSInvoker.invoke(JAXRSInvoker.java:189) [cxf-rt-frontend-jaxrs-3.1.10.jar:3.1.10]
at org.apache.cxf.jaxrs.JAXRSInvoker.invoke(JAXRSInvoker.java:99) [cxf-rt-frontend-jaxrs-3.1.10.jar:3.1.10]
at org.apache.cxf.interceptor.ServiceInvokerInterceptor$1.run(ServiceInvokerInterceptor.java:59) [cxf-core-3.1.10.jar:3.1.10]
at org.apache.cxf.interceptor.ServiceInvokerInterceptor.handleMessage(ServiceInvokerInterceptor.java:96) [cxf-core-3.1.10.jar:3.1.10]
at org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:308) [cxf-core-3.1.10.jar:3.1.10]
at org.apache.cxf.transport.ChainInitiationObserver.onMessage(ChainInitiationObserver.java:121) [cxf-core-3.1.10.jar:3.1.10]
at org.apache.cxf.transport.http.AbstractHTTPDestination.invoke(AbstractHTTPDestination.java:262) [cxf-rt-transports-http-3.1.10.jar:3.1.10]
at org.apache.cxf.transport.servlet.ServletController.invokeDestination(ServletController.java:234) [cxf-rt-transports-http-3.1.10.jar:3.1.10]
at org.apache.cxf.transport.servlet.ServletController.invoke(ServletController.java:208) [cxf-rt-transports-http-3.1.10.jar:3.1.10]
at org.apache.cxf.transport.servlet.ServletController.invoke(ServletController.java:160) [cxf-rt-transports-http-3.1.10.jar:3.1.10]
at org.apache.cxf.transport.servlet.CXFNonSpringServlet.invoke(CXFNonSpringServlet.java:180) [cxf-rt-transports-http-3.1.10.jar:3.1.10]
at org.apache.cxf.transport.servlet.AbstractHTTPServlet.handleRequest(AbstractHTTPServlet.java:299) [cxf-rt-transports-http-3.1.10.jar:3.1.10]
at org.apache.cxf.transport.servlet.AbstractHTTPServlet.doGet(AbstractHTTPServlet.java:223) [cxf-rt-transports-http-3.1.10.jar:3.1.10]
at javax.servlet.http.HttpServlet.service(HttpServlet.java:687) [jboss-servlet-api_3.1_spec-1.0.0.Final-redhat-1.jar!/:1.0.0.Final-redhat-1]
at org.apache.cxf.transport.servlet.AbstractHTTPServlet.service(AbstractHTTPServlet.java:274) [cxf-rt-transports-http-3.1.10.jar:3.1.10]
at io.undertow.servlet.handlers.ServletHandler.handleRequest(ServletHandler.java:85) [undertow-servlet-1.3.31.Final-redhat-3.jar!/:1.3.31.Final-redhat-3]
at io.undertow.servlet.handlers.security.ServletSecurityRoleHandler.handleRequest(ServletSecurityRoleHandler.java:62) [undertow-servlet-1.3.31.Final-redhat-3.jar!/:1.3.31.Final-redhat-3]
at io.undertow.servlet.handlers.ServletDispatchingHandler.handleRequest(ServletDispatchingHandler.java:36) [undertow-servlet-1.3.31.Final-redhat-3.jar!/:1.3.31.Final-redhat-3]
at org.wildfly.extension.undertow.security.SecurityContextAssociationHandler.handleRequest(SecurityContextAssociationHandler.java:78) [wildfly-undertow-7.0.9.GA-redhat-3.jar!/:7.0.9.GA-redhat-3]
at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43) [undertow-core-1.3.31.Final-redhat-3.jar!/:1.3.31.Final-redhat-3]
at io.undertow.servlet.handlers.security.SSLInformationAssociationHandler.handleRequest(SSLInformationAssociationHandler.java:131) [undertow-servlet-1.3.31.Final-redhat-3.jar!/:1.3.31.Final-redhat-3]
at io.undertow.servlet.handlers.security.ServletAuthenticationCallHandler.handleRequest(ServletAuthenticationCallHandler.java:57) [undertow-servlet-1.3.31.Final-redhat-3.jar!/:1.3.31.Final-redhat-3]
at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43) [undertow-core-1.3.31.Final-redhat-3.jar!/:1.3.31.Final-redhat-3]
at io.undertow.security.handlers.AbstractConfidentialityHandler.handleRequest(AbstractConfidentialityHandler.java:46) [undertow-core-1.3.31.Final-redhat-3.jar!/:1.3.31.Final-redhat-3]
at io.undertow.servlet.handlers.security.ServletConfidentialityConstraintHandler.handleRequest(ServletConfidentialityConstraintHandler.java:64) [undertow-servlet-1.3.31.Final-redhat-3.jar!/:1.3.31.Final-redhat-3]
at io.undertow.security.handlers.AuthenticationMechanismsHandler.handleRequest(AuthenticationMechanismsHandler.java:60) [undertow-core-1.3.31.Final-redhat-3.jar!/:1.3.31.Final-redhat-3]
at io.undertow.servlet.handlers.security.CachedAuthenticatedSessionHandler.handleRequest(CachedAuthenticatedSessionHandler.java:77) [undertow-servlet-1.3.31.Final-redhat-3.jar!/:1.3.31.Final-redhat-3]
at io.undertow.security.handlers.NotificationReceiverHandler.handleRequest(NotificationReceiverHandler.java:50) [undertow-core-1.3.31.Final-redhat-3.jar!/:1.3.31.Final-redhat-3]
at io.undertow.security.handlers.AbstractSecurityContextAssociationHandler.handleRequest(AbstractSecurityContextAssociationHandler.java:43) [undertow-core-1.3.31.Final-redhat-3.jar!/:1.3.31.Final-redhat-3]
at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43) [undertow-core-1.3.31.Final-redhat-3.jar!/:1.3.31.Final-redhat-3]
at org.wildfly.extension.undertow.security.jacc.JACCContextIdHandler.handleRequest(JACCContextIdHandler.java:61) [wildfly-undertow-7.0.9.GA-redhat-3.jar!/:7.0.9.GA-redhat-3]
at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43) [undertow-core-1.3.31.Final-redhat-3.jar!/:1.3.31.Final-redhat-3]
at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43) [undertow-core-1.3.31.Final-redhat-3.jar!/:1.3.31.Final-redhat-3]
at io.undertow.servlet.handlers.ServletInitialHandler.handleFirstRequest(ServletInitialHandler.java:285) [undertow-servlet-1.3.31.Final-redhat-3.jar!/:1.3.31.Final-redhat-3]
at io.undertow.servlet.handlers.ServletInitialHandler.dispatchRequest(ServletInitialHandler.java:264) [undertow-servlet-1.3.31.Final-redhat-3.jar!/:1.3.31.Final-redhat-3]
at io.undertow.servlet.handlers.ServletInitialHandler.access$000(ServletInitialHandler.java:81) [undertow-servlet-1.3.31.Final-redhat-3.jar!/:1.3.31.Final-redhat-3]
at io.undertow.servlet.handlers.ServletInitialHandler$1.handleRequest(ServletInitialHandler.java:175) [undertow-servlet-1.3.31.Final-redhat-3.jar!/:1.3.31.Final-redhat-3]
at io.undertow.server.Connectors.executeRootHandler(Connectors.java:324) [undertow-core-1.3.31.Final-redhat-3.jar!/:1.3.31.Final-redhat-3]
at io.undertow.server.HttpServerExchange$1.run(HttpServerExchange.java:803) [undertow-core-1.3.31.Final-redhat-3.jar!/:1.3.31.Final-redhat-3]
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) [?:1.8.0_161]
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) [?:1.8.0_161]
at java.lang.Thread.run(Thread.java:748) [?:1.8.0_161]

【问题讨论】:

  • 尝试输入null 密码。
  • 当我使用 keytool 时它会提示输入密码,所以加载时不应该使用它吗?其他例子也表明它也被通过了。
  • 尝试了 null 相同的错误“无效的密钥库格式”。
  • 用于创建和手动检查密钥库的 keytool 是否与 相同 1.8 版本和相同的配置(特别是 JRE/lib/security/java.security 文件) ,还是不同?在 8 月初、8 月底和 9 日之间,密钥库处理发生了变化。你能显示文件前 10 个字节左右的十六进制转储吗? @Andreas:错误的密码永远不会抛出“无效格式”,它会抛出“篡改或密码不正确”
  • EF BF BD 是 U+FFFD '替换'的 UTF-8 编码。这看起来像构建您的 JAR 的任何东西,或者可能是“准备”文件 for JAR 的某个步骤,将这些数据视为 text 而它不是,因此严重混乱它。

标签: java keystore


【解决方案1】:

二进制 JKS 文件可能被 Maven 资源插件过滤,导致文件损坏,这是一个很常见的问题:

Maven corrupts WAV file when copying to Java resource dir during build

Maven corrupting binary files in source/main/resources when building jar

generated certificate stops working when moved to resources folder

二进制文件基本上被视为文本文件,因此 jar 中的文件以 UTF-8 字符 (0xEFBFBDEFBFBD) 开头,而不是 JKS 的幻数 (0xFEEDFEED)。

Resources Plugin documentation 包含一个明确的警告:

不要过滤图像等二进制内容的文件!这 很可能会导致输出损坏。

可能的解决方案是:

  • 将资源文件夹拆分为一个被过滤的文件夹和一个未被过滤的文件夹(请参阅here
  • 全局禁用过滤扩展名为 .jks 的文件(请参阅here

【讨论】:

    【解决方案2】:

    确保避免过滤您的密钥库文件 jks

    喜欢

    <resources>
                <resource>
                    <directory>src/main/resources</directory>
                    <filtering>true</filtering>
                    <excludes>
                        <exclude>**/*.jks</exclude>
                    </excludes>
                </resource>
                <resource>
                    <directory>src/main/resources</directory>
                    <filtering>false</filtering>
                    <includes>
                        <include>**/*.jks</include>
                    </includes>
                </resource>
            </resources>
    

    【讨论】:

      【解决方案3】:

      基于Omikrom 答案:

      二进制文件基本上被视为文本文件,因此 jar 中的文件以 UTF-8 字符 (0xEFBFBDEFBFBD) 开头,而不是 JKS 的幻数 (0xFEEDFEED)。

      我在 pom.xml 文件的属性部分添加了这两行

      <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
      <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
      

      成功了

      【讨论】:

        【解决方案4】:

        免责声明:这还不是一个完整的答案,但我需要一个与 OP 讨论的工具。如果这不能导致解决方案,我将再次删除答案。

        我在 POJO 中复制了您的情况,如下所示:

        $ openssl req -new -newkey rsa:4096 -x509 -sha256 -days 365 -nodes -out MyCertificate.crt -keyout MyKey.key
        (answer all questions with RETURN = accept defaults)
        
        $ keytool -v -import -alias devserver -file MyCertificate.crt -keystore src/main/resources/cacerts.jks -storetype JKS
        Enter keystore password:  testtest
        Re-enter new password: testtest
        (...)
        Trust this certificate? [no]:  yes
        Certificate was added to keystore
        [Storing src/main/resources/cacerts.jks]
        
        $ keytool -list -keystore src/main/resources/cacerts.jks
        Enter keystore password:  testtest
        Keystore type: JKS
        Keystore provider: SUN
        
        Your keystore contains 1 entry
        
        devserver, 24.08.2019, trustedCertEntry,
        Certificate fingerprint (SHA-256): A2:E1:49:FB:9C:26:6B:8A:21:45:A4:AA:F4:86:A0:A7:82:B8:08:BE:75:A6:BF:E8:F5:13:9E:31:23:8E:B0:71
        

        现在在 Maven JAR 模块中创建一个类,类似于 OP 显示的代码:

        package de.scrum_master.stackoverflow;
        
        import java.io.IOException;
        import java.io.InputStream;
        import java.security.KeyStore;
        import java.security.KeyStoreException;
        import java.security.NoSuchAlgorithmException;
        import java.security.cert.CertificateException;
        
        public class CustomTrustManager {
          public static void main(String[] args) throws KeyStoreException, CertificateException, NoSuchAlgorithmException, IOException {
            InputStream stream;
            stream = Thread.currentThread().getContextClassLoader().getResourceAsStream("cacerts.jks");
            System.out.println(stream);
            if (stream == null) {
              stream = CustomTrustManager.class.getClassLoader().getResourceAsStream("cacerts.jks");
            }
            if(stream == null) {
              System.out.println("Unable to load cacerts.jks. This is needed to make HTTPS connections to internal servers.");
              throw new RuntimeException("Keystore not found");
            }
        
            KeyStore myTrustStore = KeyStore.getInstance("JKS");
            myTrustStore.load(stream, "testtest".toCharArray());
            System.out.println("Keystore loaded");
          }
        }
        

        现在使用mvn clean package 构建项目并运行它:

        $ java -cp target/my-sample-1.0-SNAPSHOT.jar de.scrum_master.stackoverflow.CustomTrustManager
        sun.net.www.protocol.jar.JarURLConnection$JarURLInputStream@3d4eac69
        Keystore loaded
        

        所以基本上你的方法应该有效。如果没有,它可以连接到

        • 类加载(但我不这么认为,因为似乎可以找到密钥库),
        • 我在您的调用堆栈中看到的 AspectJ(或者更确切地说只是 Spring AOP)的东西(也不太可能),
        • 您自己的自定义信任管理器或您的“风险计量器”类所做的任何事情。

        请检查您在应用程序中使用的完全相同的密钥库是否像我的示例中那样从简单的 JAR 工作,没有容器或其他花哨的东西。如果是这样,您就知道问题不在于您的密钥库。

        那么请在这里提供一些反馈。

        【讨论】:

        • 您创建了一个 PKCS12(不是 JKS)密钥库,即使您将其命名为 .jks,可能是使用 Java 9 或更高版本 keytool。然后,您尝试将其读取为 JKS,这应该并且确实失败了。这里的其他一切都无关紧要。
        • 首先,使用参数“JKS”加载 PKCS12 密钥库确实没有失败,否则我不会发布没有错误的日志。您甚至尝试过复制我所做的事情吗?其次,我创建了一个新的密钥库,这次使用了附加参数-storetype JKS。我还更新了日志输出,您会看到它仍在工作,密钥库已正常加载。所以我再次向 OP 询问他的密钥库,以帮助我们重现他的问题。我的解决方案有效,它实际上使用了 OP 的代码。
        • 或者,也许 OP 会告诉我们他使用哪个 OpenSSL(或其他工具)命令行生成了证书。
        • OP 告诉我们他们使用“Java 1.8”,更具体地说是“Java 1.8.0_161 64 位”并告诉我们文件开始 FEED FEED(是 JKS 的幻数),但 jar 条目 not。抱歉,当你说你复制了我以为你复制了异常(但仔细观察我发现你没有),我也没有注意到 Oracle 在 9-12 保留了 'keystore.type.compat=true',他们只是将它移到我没有在寻找它的 conf/security 中,所以是的,JKS 提供程序(stil)实际上可以读取 PKCS12。
        • 我只是在展示通常应该如何工作。 OP 可以使用她的 JAR 中的密钥库并使用我的 MCVE 在容器外对其进行测试,以便为我们获取更多信息。这样我们就可以确定密钥库本身是否有问题,正如您所说,这可能意味着构建/打包过程在某种程度上被破坏了。但是,如果她提取的密钥库适用于我的示例,则资源类加载或过滤会出现问题,正如我之前所说。我们无法确定她是否不尝试提供反馈。
        猜你喜欢
        • 2020-10-25
        • 2014-07-02
        • 2023-03-20
        • 2021-08-12
        • 1970-01-01
        • 2021-08-14
        • 2020-08-26
        • 2019-04-12
        相关资源
        最近更新 更多