【发布时间】:2020-12-31 14:08:30
【问题描述】:
我正在开发一个 Ionic-Angular 应用程序,但由于明文流量而面临很多问题。所以我决定在编码的同时切换到 https,但这并不容易。
我打开这个问题并提出我找到的答案以保持跟踪,如果您也想这样做,希望能为您节省一些时间。
【问题讨论】:
标签: ionic-framework https ssl-certificate
我正在开发一个 Ionic-Angular 应用程序,但由于明文流量而面临很多问题。所以我决定在编码的同时切换到 https,但这并不容易。
我打开这个问题并提出我找到的答案以保持跟踪,如果您也想这样做,希望能为您节省一些时间。
【问题讨论】:
标签: ionic-framework https ssl-certificate
您的开发机器需要一个主机名。此名称将在证书中声明,并且将使用此主机名访问 https 服务(URL 必须类似于 https://[hostname]:... 才能通过证书检查)。
如果您的网络还没有 DNS,您可以使用托管在您的开发机器上的 MaraDNS 之类的东西(有关示例配置,请参阅 P.S.)。
self_signed_template.config:
[req]
default_bits = 2048
default_md = sha256
prompt = no
default_keyfile = [hostname]_self_signed_key.pem
encrypt_key = no
distinguished_name = dn
req_extensions = v3_req
x509_extensions = v3_req
[dn]
C = PF
ST = Tahiti
L = Papeete
O = c4-soft
emailAddress = ch4mp@c4-soft.com
CN = [hostname]
[v3_req]
subjectAltName = critical, @alt_names
basicConstraints = critical, CA:false
keyUsage = critical, keyCertSign, nonRepudiation, digitalSignature, keyEncipherment
extendedKeyUsage = critical, serverAuth, clientAuth
[alt_names]
DNS.1 = [hostname]
DNS.2 = localhost
DNS.3 = 10.0.2.2
self_signed.sh
#!/bin/bash
if [ -z "$1" ]
then
echo "Usage:"
echo ""
echo "self_signed.sh key_password [java_home] [hostname] [store_password] [certificates_directory_path] [cacerts_password]"
echo ""
echo " - java_home is defaulted to $JAVA_HOME"
echo " - hostname is defaulted to $HOSTNAME"
echo " - store_password is defaulted to key_password"
echo " - certificates_directory_path is defaulted to current diretory"
echo " - cacerts_password is defaulted to changeit"
echo ""
echo "Sample:"
echo "./self_signed.sh \"secr3!\" \"C:/Java/jdk1.8.0_281\" \"bravo-ch4mp\""
echo ""
exit 1
else
echo "#------------------------------------------"
echo "# This is a no-op script"
echo "# Copy / paste output to:"
echo "# - generate certificate files"
echo "# - import certificates into cacerts file"
echo "#------------------------------------------"
KEY_PASSWORD="${1}"
echo "# key password: $KEY_PASSWORD"
if [ -z "$2" ]
then
if [ -z "$JAVA_HOME" ]
then
echo "ERROR: could not locate java home"
exit 1
else
JAVA=$JAVA_HOME
fi
else
JAVA=$2
fi
JAVA=$(echo $JAVA | sed 's/\\/\//g')
echo "# java home: $JAVA"
if [ -f "${JAVA}/lib/security/cacerts" ]
then
# recent JDKs and JREs style
CACERTS="${JAVA}/lib/security/cacerts"
elif [ -f "${JAVA}/jre/lib/security/cacerts" ]
then
# legacy JDKs style (1.8 and older)
CACERTS="${JAVA}/jre/lib/security/cacerts"
else
echo "ERROR: could not locate cacerts under ${JAVA}"
exit 1
fi
echo "# cacerts path: $CACERTS"
if [ -z "${3}" ]
then
HOST="$HOSTNAME"
else
HOST="${3}"
fi
echo "# host (certificate CN): $HOST"
if [ -z "${4}" ]
then
STORE_PASSWORD="$KEY_PASSWORD"
else
STORE_PASSWORD="${4}"
fi
echo "# store password : $STORE_PASSWORD"
if [ -z "${5}" ]
then
CERTIF_DIR="."
else
CERTIF_DIR="${5}"
fi
echo "# certificates directory path: $CERTIF_DIR"
CERTIF_DIR=$(echo $CERTIF_DIR | sed 's/\\/\//g')
if [ -z "${6}" ]
then
CACERTS_PASSWORD="changeit"
else
CACERTS_PASSWORD="${6}"
fi
echo "# cacerts password: $CACERTS_PASSWORD"
echo "#------------------------------------------"
fi
echo ""
rm -f ${HOST}_self_signed.config;
sed 's/\[hostname\]/'${HOST}'/g' "${CERTIF_DIR}/self_signed_template.config" > "${CERTIF_DIR}/${HOST}_self_signed.config"
echo openssl req -config \"${CERTIF_DIR}/${HOST}_self_signed.config\" -new -keyout \"${CERTIF_DIR}/${HOST}_self_signed_key.pem\" -out \"${CERTIF_DIR}/${HOST}_self_signed_cert.pem\" -reqexts v3_req
echo ""
echo openssl x509 -req -days 365 -extfile \"${CERTIF_DIR}/${HOST}_self_signed.config\" -in \"${CERTIF_DIR}/${HOST}_self_signed_cert.pem\" -extensions v3_req -signkey \"${CERTIF_DIR}/${HOST}_self_signed_key.pem\" -out \"${CERTIF_DIR}/${HOST}_self_signed.crt\"
echo ""
echo openssl pkcs12 -export -in \"${CERTIF_DIR}/${HOST}_self_signed.crt\" -inkey \"${CERTIF_DIR}/${HOST}_self_signed_key.pem\" -name ${HOST}_self_signed -password pass:${KEY_PASSWORD} -out \"${CERTIF_DIR}/${HOST}_self_signed.pfx\"
echo ""
echo \"${JAVA}/bin/keytool\" -importkeystore -srckeystore \"${CERTIF_DIR}/${HOST}_self_signed.pfx\" -srcstorepass \"${STORE_PASSWORD}\" -srcstoretype pkcs12 -srcalias ${HOST}_self_signed -destkeystore \"${CERTIF_DIR}/${HOST}_self_signed.jks\" -deststoretype PKCS12 -deststorepass ${STORE_PASSWORD} -destalias ${HOST}_self_signed
echo ""
echo \"${JAVA}/bin/keytool\" -importkeystore -srckeystore \"${CERTIF_DIR}/${HOST}_self_signed.pfx\" -srcstorepass \"${STORE_PASSWORD}\" -srcstoretype pkcs12 -srcalias ${HOST}_self_signed -destkeystore \"${CACERTS}\" -deststorepass ${CACERTS_PASSWORD} -destalias ${HOST}_self_signed
echo ""
然后运行 ./self_signed.sh "secr3!" C:/Java/jdk1.8.0_281 之类的东西。
为每个 JDK/JRE 执行 ./self_signed.sh 然后
只需在第一次执行时复制/粘贴/运行所有输出命令,last command only(在 JDK / JRE cacerts 文件中导入证书)从第二次执行开始(否则您将丢失以前的证书)。
在 Java 的 cacerts 中导入证书可能需要管理员权限。
在 Windows 上,Git Bash 在路径上包含所有 sed、openssl 和 keytool。
如果您将此证书添加到受信任的根权限,您的浏览器在导航诸如 https://[hostname]:... 之类的 URL 时将不会显示错误或警告。
在 Windows 上,这可以通过 certmgr.msc 完成(右键单击受信任的根权限,然后导入)。如果您在其他操作系统上成功执行此操作,请发表评论。
编辑angular.json,在your-project/architect/serve/options/下设置“sslCert”和“sslKey”,分别指向前面生成的[hostname]_self_signed.crt和[hostname]_self_signed_key.pem。
这足以在运行ionic serve --ssl --host=[hostname] 或ionic capacitor run android -l --ssl --host=[hostname] 时选择正确的证书
提醒:android资源文件夹是你项目下的android/app/src/main/res/或Android Studio中的app/res/
首先,将[hostname]_self_signed.crt 复制到raw 资源,将-(如果有)替换为主机名中的_。
在 xml 资源中创建network_security_config.xml(注意修改后的主机名)
<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
<base-config cleartextTrafficPermitted="true">
<trust-anchors>
<certificates src="@raw/[hostname]_self_signed"/>
<certificates src="system"/>
</trust-anchors>
</base-config>
</network-security-config>
重要提示:如果您的所有流量都是通过 https 提供的,您应该将 cleartextTrafficPermitted 设置为 false(这是自 Android 9 以来的默认值)。至少考虑为产品构建这样做。
最后,编辑AndroidManifest.xml 并将android:networkSecurityConfig="@xml/network_security_config" 添加到您的<application > 标签中
我没有使用 iOS 的经验,如果您可以使用,请随时发表评论或添加答案。
嗯...这真的取决于您使用的堆栈。几个示例:
ASPNETCORE_Kestrel__Certificates__Default__Password 和 ASPNETCORE_Kestrel__Certificates__Default__Path,第二个指向 [hostname]_self_signed.pfx
[hostname]_self_signed.jks 复制到 src/main/resources/ 并设置 server.ssl 属性P.S. 我用于 MaraDNS 的 dwood3rc.txt 文件:
#upstream_servers = {}
#upstream_servers["."]="8.8.8.8, 8.8.4.4" # Servers we connect to
root_servers = {}
# ICANN DNS root servers
root_servers["."]="198.41.0.4, 199.9.14.201, 192.33.4.12, 199.7.91.13,"
root_servers["."]+="192.203.230.10, 192.5.5.241, 192.112.36.4, "
root_servers["."]+="198.97.190.53, 192.36.148.17, 192.58.128.30, "
root_servers["."]+="193.0.14.129, 199.7.83.42, 202.12.27.33"
# local DNS server
root_servers["bravo-ch4mp."]="192.168.1.181"
root_servers["local."]="192.168.1.181"
# The IP this program has
bind_address="127.0.0.1, 192.168.1.181, 192.168.1.132"
# The IPs allowed to connect and use the cache
recursive_acl = "127.0.0.1/16, 192.168.0.1/16"
chroot_dir = "/etc/maradns"
# This is the file Deadwood uses to read the cache to and from disk
cache_file = "dw_cache_bin"
filter_rfc1918 = 0
ip4 = {}
ip4["bravo-ch4mp."] = "192.168.1.181"
ip6 = {}
一旦我的开发机器上的 DNS 服务器启动 (net start deadwood)(并且还配置了防火墙...),我将客户端配置为将其用作主 DNS(编辑不需要根设备的 wifi 网络属性)等瞧!
P.S.2 Keycloak 独立配置允许测试设备通过 https 连接到 OpenId 端点
将[hostname]_self_signed.jks 复制到standalone/configuration/。
编辑standalone/configuration/standalone.xml 以将${jboss.bind.address:127.0.0.1} 替换为${jboss.bind.address:0.0.0.0}。保存并关闭。
使用bin/standalone[.bat|.sh] 启动Keycloak,然后使用bin/jboss-cli[.bat|.sh]:
connect
/subsystem=keycloak-server/spi=hostname/provider=default:write-attribute(name=properties.frontendUrl,value="https://[hostname]:8443/auth")
/core-service=management/security-realm=UndertowRealm:add()
/core-service=management/security-realm=UndertowRealm/server-identity=ssl:add(keystore-path=[hostname]_self_signed.jks, keystore-relative-to=jboss.server.config.dir, keystore-password=[keystore_password])
/subsystem=undertow/server=default-server/https-listener=https:write-attribute(name=security-realm, value=UndertowRealm)
reload
【讨论】: