Flutter ACME客户端插件ls_acme_client的使用
Flutter ACME客户端插件ls_acme_client的使用
Dart Acme Client
一个基于RFC 8555的ACME V2兼容客户端,用Dart语言编写。
目录
前言
由于此包是纯Dart编写的,因此可以在所有支持Dart的平台上运行。这包括像Flutter、Angular Dart等框架的使用。此外,该包也可以用于通过dart2native编译的命令行工具或REST服务。
注意: 如果发现错误、有疑问或功能请求,请随时创建拉取请求或提交问题。
安装
在pubspec.yaml
文件中添加以下依赖项:
dependencies:
ls_acme_client: ^1.1.0
导入
通过以下方式导入包:
import 'package:ls_acme_client/acme_client.dart';
Acme客户端
这是一个基于RFC 8555的简单ACME客户端,能够与任何基于该RFC的ACME服务器通信,包括Let’s Encrypt。
客户端设置
通过调用构造函数并传递适当的参数来创建新客户端:
// 创建一个新的Acme客户端实例
var client = AcmeClient(
'https://acme-server.com', // ACME服务器的基地址
privateKeyPem, // 私钥(PEM格式)
publicKeyPem, // 公钥(PEM格式)
true, // 是否接受条款
['mailto:jon@doe.com'], // 联系邮箱列表
);
// 初始化客户端,从服务器获取目录和账户信息
await client.init();
说明:
baseUrl
: ACME服务器的基地址。privateKeyPem
: PEM格式的私钥。publicKeyPem
: PEM格式的公钥。acceptTerms
: 是否接受条款。contacts
: 邮箱地址列表,格式为'mailto:xxx@yyy.com'
。
提示: 如果需要生成RSA/ECC密钥对,可以查看Basic Utils包,其中包含生成密钥对和将其格式化为PEM所需的工具。
申请证书颁发
下单
通过创建新的Order
对象并添加要放入证书中的标识符来下单:
// 创建订单对象
var order = Order(
identifiers: [
Identifiers(type: 'dns', value: 'example.com') // 添加DNS标识符
]
);
// 向ACME服务器提交订单
var newOrder = await client.order(order);
获取授权数据
通过调用getAuthorization()
方法获取每个订单的授权数据:
// 获取授权数据
var auth = await client.getAuthorization(newOrder!);
// 遍历授权数据
for (var a in auth) {
print(a.status); // 打印授权状态
}
获取授权挑战
对于每个返回的授权,都有多个挑战。可以选择其中一个挑战来证明对标识符的控制权并完成授权请求:
// 获取HTTP挑战数据
for (var a in auth) {
var data = a.getHttpDcvData();
}
// 获取DNS挑战数据
for (var a in auth) {
var data = a.getDnsDcvData();
}
自测
建议提前检查挑战是否通过,可以通过适当的方法进行测试。通过maxAttempts
参数可以调整尝试次数,默认为15次。
注意: DNS自测使用Google DNS Rest API来获取资源记录。
// 测试HTTP挑战
var self = await client.selfHttpTest(data); // HttpDcvData
if (!self) {
print('Selftest failed, no file found or content mismatch');
}
// 测试DNS挑战
var self = await client.selfDNSTest(data); // DnsDcvData
if (!self) {
print('Selftest failed, no DNS record found');
}
触发验证
调用validate()
方法通知ACME服务器检查挑战,并每隔4秒轮询一次授权状态,直到状态变为“有效”。默认轮询次数为15次。
// 触发验证
var data; // HttpDcvData 或 DnsDcvData
var authValid = await client.validate(data.challenge);
if (!authValid) {
print('Authorization failed, exit');
}
完成订单
如果所有授权的状态均为“有效”,则通过发送CSR完成订单。CSR会根据RFC规则自动格式化(Base64Url编码且无头部)。
// 发送CSR完成订单
var finalOrder = await client.finalizeOrder(newOrder, csr);
获取证书
通过getCertificate()
方法获取证书列表,传入已完成的订单对象:
// 获取证书
var certs = await client.getCertificate(finalOrder);
// 打印证书
for (var cert in certs) {
print(cert); // 输出证书内容
}
更多关于Flutter ACME客户端插件ls_acme_client的使用的实战教程也可以访问 https://www.itying.com/category-92-b0.html
更多关于Flutter ACME客户端插件ls_acme_client的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
ls_acme_client
是一个用于 Flutter 的 ACME 客户端插件,它允许你在 Flutter 应用中与 ACME 服务器进行交互,以获取和管理 TLS/SSL 证书。ACME(Automatic Certificate Management Environment)是一个协议,通常与 Let’s Encrypt 等服务一起使用,用于自动化证书的获取和续订。
安装 ls_acme_client
首先,你需要在 pubspec.yaml
文件中添加 ls_acme_client
依赖项:
dependencies:
flutter:
sdk: flutter
ls_acme_client: ^1.0.0 # 请使用最新版本
然后运行 flutter pub get
来获取依赖项。
使用 ls_acme_client
以下是一个简单的示例,展示如何使用 ls_acme_client
获取证书:
import 'package:ls_acme_client/ls_acme_client.dart';
void main() async {
// 创建 ACME 客户端实例
final acmeClient = AcmeClient(
directoryUrl: 'https://acme-v02.api.letsencrypt.org/directory', // ACME 服务器目录 URL
);
// 创建账户
final account = await acmeClient.createAccount(
email: 'your-email@example.com',
agreeToTerms: true,
);
// 创建订单
final order = await acmeClient.createOrder(
identifiers: ['example.com', 'www.example.com'],
);
// 获取授权
final authorizations = await acmeClient.getAuthorizations(order);
// 完成挑战(例如 HTTP-01 挑战)
for (final auth in authorizations) {
final challenge = auth.http01Challenge;
// 在这里,你需要将 challenge.token 和 challenge.keyAuthorization 部署到你的服务器
// 例如,将 keyAuthorization 放在 `/.well-known/acme-challenge/${challenge.token}` 路径下
await acmeClient.completeChallenge(challenge);
}
// 等待挑战完成
await acmeClient.waitForAuthorizations(order);
// 生成 CSR(证书签名请求)
final csr = generateCsr(
commonName: 'example.com',
altNames: ['www.example.com'],
);
// 完成订单
final certificate = await acmeClient.finalizeOrder(order, csr);
// 下载证书
final certChain = await acmeClient.downloadCertificate(certificate);
// 打印证书链
print(certChain);
}