Smart-ID 节点客户端
此库提供现代的,开发者友好的与官方的融合 Smart-ID REST API v3 (英语) 从 SK ID 解决方案电子身份认证和数字签名 爱沙尼亚, (中文(简体) ), 拉脱维亚,以及 立陶宛。 。 。 .
它完全建在 类型脚本,杠杆化了已经建立起来的密码库,并提供了遵循构建器模式的清洁模块化设计,使开发者能够完全控制请求构建,安全验证,以及交互流.
图书馆总结了许多与Smart-ID合作的低层次复杂性,同时严格遵循正式规格,并提供必要的工具来建立这两个系统 交叉设备 (例如,浏览器到移动)和 同一设备 (如:移动应用)认证流.
这个DEMO是和 网点JS 并与 民主行动办:https://smartid.joosep.org 智能ID系统.
目录
概览
特征
- 支持 Smart-ID v3( 2025年6月)
- 强烈键入请求构建器( Device 链接和通知认证)
- 使用证书信任检查进行验证
- Smart-ID 方案识别( 最终实体证书) 执行
- 签字重建和核查逻辑
- 支持 VC 类型: 数字 4 通知流
- 会话特写和用户挑战验证符
- 清洁、可扩展、最小的依赖性(crypto、node-forge、pkijs)
这个库执行基于协议3版本的主要Smart-ID RP API流.
主要认证流量
交叉设备使用个案
使用大小写:RP会话位于安装Smart-ID应用的手机之外的一个单独的设备上.
例如,用户正在使用PC浏览器访问RP网站或平板电脑访问RP应用程序.
使用同一设备的案件
使用大小写:RP前端(无论是RP应用还是移动浏览器访问的网站)都与Smart-ID应用在同一个移动设备上.
最终用户正在使用移动应用程序或RP检测到用户在移动浏览器上,因此可以假定用户打算在同一个设备上使用Smart-ID应用程序.
强烈倾向于采用BASE/v3/*/device-link/匿名端点作为同声端点,除非已经为本届会议确定了用户的文档编号。 这些端点提供了更好的用户体验,因为不需要用户标识条目,而带有回调的设备链接则提供了最好的安全保护.
然而,还应提供退后选择,以切换到交叉设备使用案例.
教学:
教学: DEMO 和教学 参考: OpenAPI 规格
这个图书馆是如何运作的
此库遵循直截了当的流程:
- 使用
AuthenticationRequestBuilder建造适当的有效载荷. - 使用可用的五个请求之一发送请求
SmartIdAuthClient基于您的使用大小写的方法 :
-
getAuthenticateAnonymousDeviceLink(requestPayload)
建议赔偿额 同一设备 假设(Web2App / App2App),用户的文档号码尚不得而知. -
getAuthenticateDeviceLinkByEtsi(idCode, requestPayload)
对于 交叉设备 或当用户的身份代码可用时使用同一设备. -
getAuthenticateDeviceLinkByDocument(documentNumber, requestPayload)
当用户的文档编号已经知道时. -
startAuthenticateNotificationByEtsi(idCode, requestPayload)
以通知为基础的身份认证. -
startAuthenticateNotificationByDocument(documentNumber, requestPayload)
基于通知的带有文档编号的认证.
- 单位 网络2App 或者说 附录2App 假设,你可以选择使用
CallbackUrlValidator以验证回调参数. - 会议结束后,请使用
AuthenticationResponseValidator以验证最后的 Smart-ID 响应.
如果需要,用户可以自由执行额外的验证逻辑或完全取代内置验证过程.
安装
npm install @arendajaelu/smart-id-node-client
开始前
这个库是为已经熟悉Smart-ID系统及其技术工作流程的开发者设计的.
如果您是新到 Smart-ID 或尚未设置您的开发者环境, 请先阅读 SK ID 解决方案提供的官方 Smart-ID Demo 文档 :
👉 https://sk-eid.github.io/smart-id-documentation/demo.html 页面存档备份,存于互联网档案馆
正式文件解释了Smart-ID概念,注册程序,以及如何获得开发和测试所需的演示证书.
只有在您成功注册了演示访问并理解了基本的 Smart-ID API 结构后,才开始整合此库 .
实例用法
import { SmartIdAuthClient, AuthenticationRequestBuilder } from 'smart-id-node-client';
const client = new SmartIdAuthClient()
.setApiEndpoint('https://sid.demo.sk.ee/smart-id-rp/v3');
const builder = new AuthenticationRequestBuilder()
.withInitialCallbackUrl('https://example.com/callback')
.withCertificateLevel('QUALIFIED');
const requestPayload = builder.build();
const session = await client.getAuthenticateAnonymousDeviceLink(requestPayload);
console.log(session);
认证请求构建器
认证请求构建(Authoration ArequestBuilder Class)提供了一个方便开发者,可配置的方法来构建有效的智能ID设备链接认证或通知认证请求的有效载荷.
这个构建器旨在简化有效载荷构造,减少人为出错,并确保生成的请求符合智能ID协议的预期. 由此产生的有效载荷可直接与SmartIdAuthClient一起使用以启动认证会话.
- 构建者自动生成了rpChallenge并处理Base64中的交互编码.
- 它支持生成DuiceLink(如QR,Web2App,App2App)和通知认证请求.
- 您保留了对可选字段的全部控制, 如初始CallbackUrl, 能力和请求Properties .
注:库在构建器阶段不执行任何I/O或网络通信——它只准备有效载荷. 通过认证请求客户端( SmartIdAuthClient) 单独发送请求
验证请求构建方法
| 方法 | 返回类型 | 说明 |
|---|---|---|
constructor(relyingPartyUUID, relyingPartyName) | AuthenticationRequestBuilder | 创建带有 RP 标识符的新构建者实例 . |
withInitialCallbackUrl(url) | this | 可选的 设置 Web2App 或 App2App 流量的回调 URL . |
withCertificateLevel(level) | this | 可选的 设置想要的证书级别( E)ADVANCED 或者说 QUALIFIED) (中文(简体) ). |
withHashAlgorithm(hashAlgorithm) | this | 可选的 为签名生成设置散列算法 . |
withRequestProperties(props) | this | 可选的 添加请求特定属性,例如客户端IP共享. |
withCapabilities(obj) | this | 可选的 为请求添加自定义能力. |
withInteractions(interaction) | this | 要求。 定义 Smart-ID app 上显示的用户界面交互. |
withVcType(vcType) | NotificationRequestBuilder | 切换到通知认证请求构建器 . |
build() | DeviceLinkAuthRequest | NotificationAuthRequest | 最后确定并返回请求的有效载荷供API消费. |
认证请求客户端
SmartIdAuthClient是您应用程序和Smart-ID REST API之间的主要通信层. 它提供了启动认证会话,查询会话状态,处理设备链接流(QR,Web2App,App2App)的方法,并确保适当的证书被标记用于安全通信.
这个客户端的设计具有灵活性,提供精细的智能ID集成控制,同时促进安全可靠的互动.
关键特性
- 通过匿名、ETSI ID代码或文件编号支持设备链接认证.
- 通过ETSI的ID代码或文件编号支持通知认证.
- 嵌入式支持被绑定的服务器证书和公钥被钉.
- 自动处理已知 Smart-ID 错误状态的会话投票 .
- 用于生成安全, 已签名的设备链接 URL 和 auuthCode 的功能 .
- 调用参数生成和 API 配置的帮助方法
示例使用
//Create an anonymous device link
const callbackParam = randomBytes(16).toString('hex');
const requestPayload = new AuthenticationRequestBuilder('00000000-0000-4000-8000-000000000000','DEMO')
.withInitialCallbackUrl(
`https://blueblackwhite.com/social/smartid?chksum=${callbackParam}`,
)
.withInteractions({
type: 'displayTextAndPIN',
displayText60: 'Authenticate with Smart-ID',
})
.build();
const { response, sessionStartTime } = await this.client
.setSchemeName('smart-id-demo')
.getAuthenticateAnonymousDeviceLink(requestPayload);
const link = this.client
.setSchemeName('smart-id-demo')
.createDeviceLinkUrl(response, requestPayload, sessionStartTime, {
deviceLinkType: 'Web2App',
});
SmartId认证方法
设备链接认证
- ETSI = ETSI 自然人语义识别器
| 方法 | 说明 |
|---|---|
getAuthenticateAnonymousDeviceLink(payload) | 启动匿名设备链接认证 . |
getAuthenticateDeviceLinkByEtsi(idCode, payload) | 由ETSI启动设备链接认证. |
getAuthenticateDeviceLinkByDocument(documentNumber, payload) | 按文档编号开始设备链接认证 . |
通知认证
| 方法 | 说明 |
|---|---|
startAuthenticateNotificationByEtsi(idCode, payload) | 由ETSI启动通知认证. |
startAuthenticateNotificationByDocument(documentNumber, payload) | 以文档编号开始通知认证 . |
会话处理
| 方法 | 说明 |
|---|---|
getSessionStatus(sessionID) | 获取认证会话的现状. |
pollForSessionResult(sessionID, options?) | Polls会话状态直至成功,失败或超时. |
设备链接工具
| 方法 | 说明 |
|---|---|
createDeviceLinkUrl(session, payload, sessionStartTime, opts) | 为 QR, Web2App 或 App2App 流创建已签名的 DuiceLink URL. |
generateCallbackParam() | 生成随机回调参数(例如,用于) initialCallbackUrl) (中文(简体) ). |
客户端配置
| 方法 | 说明 |
|---|---|
setPublicSslKeys(fingerprints) | 配置 SHA-256 公用密钥指针用于额外的安全性. |
setApiEndpoint(hostUrl, version?) | 覆盖 Smart-ID API 端点和版本. |
setApiVersion(version) | 更新Smart-ID API版本. |
setSchemeName(name) | 设置用于签名有效载荷的方案名称. |
setBrokeredRpName(name) | 设置设备链接 URL 生成中使用的代理 RP 名称 . |
关于安全和一体化范围的说明
支持 TLS 证书通过 pardCerts 来对服务器身份进行强固验证(首选方法) .
- 支持公用钥匙散列来进一步减轻"人入中"(MITM)攻击.
- 生成已签名的设备链接 URL 的 AuthCode, 来源于会话密钥, 确保 URL 的完整性 .
- 为测试、中转和生产环境提供对API端点配置的全面控制.
重要内容: 此库不管理 CA 证书或公钥 Pinning 密钥 。 开发者有责任安全维护、提供和旋转这些材料,作为其基础设施的一部分.
- 范围外: 该库不包括生成 DuiceLink URL 实际的 QR 代码图像的逻辑. 生成一个QR代码是直截了当的,并有意留给应用程序层,允许开发人员使用任何首选方法,例如:
import QRCode from "qrcode";
const url = client.createDeviceLinkUrl(session, payload, sessionStartTime, { deviceLinkType: "QR" });
QRCode.toFile("qrcode.png", url);
回调 Url 校验器
单位 设备链接 依赖召回 URL 的认证流程,例如 网络2App 财务报告和审定财务报表 附录2App 情景、适当处理和核实回调的URL对于确保安全、可防打网的认证进程至关重要.
根据 正式的智能识别文档,依赖方后端必须验证从Smart-ID应用程序收到的回调参数是有效的,值得信赖的,没有被篡改.
这个 Callback Url Validator 课程提供基本的公用事业,以协助这一核查进程。 它允许开发者:
- 验证预期召回参数的存在和格式.
- 请检查参数的一致性和完整性 .
- 发现明显的操纵企图.
灵活融合
此校验器可作为一个独立组件使用,也可通过.ballback UrlValidate()无缝地集成到验证器中来,实现精简,端到端的校验流量.
图书馆的设计具有灵活性:
您可以独立执行调用回调 URL 验证和 Smart-ID 会话响应验证 .
您可以在任一验证阶段插入自定义验证步骤,以适应应用程序的安全要求.
NB来了! 此校验器旨在帮助简化开发, 但鼓励开发人员审查 安全实施指南 并根据其风险状况和威胁模式进行额外的检查.
样本使用
import { CallBackUrlValidator } from "./callback-url-validator";
import { CallbackValidationEntity } from "./types";
// Example callback payload received from Smart-ID flow
const entity: CallbackValidationEntity = {
sessionSecretDigest: "computedDigestFromFrontend",
userChallengeVerifier: "randomVerifierUsedInRequest",
sessionSecret: "Base64SessionSecretUsedInRequest",
schemeName: "smart-id",
authenticationResponse: {
state: "COMPLETE",
result: {
endResult: "OK",
documentNumber: "PNOEE-1234567890",
},
signatureProtocol: "ACSP_V2",
signature: {
value: "base64SignatureValue",
userChallenge: "expectedComputedHash",
},
cert: {
value: "base64Certificate",
certificateLevel: "QUALIFIED",
},
},
};
// Perform validation
const validator = new CallBackUrlValidator(entity);
const result = validator.validate().getResult();
if (result.hasError) {
console.error("Callback validation failed:", result.errors);
} else {
console.log("Callback successfully validated!");
}
调用BackUrl校验方法
| 方法 | 返回类型 | 说明 |
|---|---|---|
constructor(entity) | CallBackUrlValidator | 以提供的内容创建新验证符 CallbackValidationEntity。 。 。 . |
validate() | this | 运行所有验证检查(会话状态,秘密摘要,用户挑战). |
getResult() | AuthenticationResult | 返回包含验证错误(如果有的话)的结果对象. |
私人帮助方法
| 方法 | 返回类型 | 说明 |
|---|---|---|
validateSessionStatus() | void | 检查会话是否成功完成, 是否存在所需的字段 . |
validateSessionSecretDigest() | void | 验证会话秘密摘要符合预期值 . |
validateUserChallengeVerifier() | void | 确认用户挑战验证符符合预期的挑战. |
computeSessionSecretDigest(secret) | string | 从提供的秘密中计算预期会话的秘密摘要. |
base64UrlEncode(buffer) | string | 将缓冲编码为 URL- safe Base64 字符串(RFC 4648). |
认证响应验证器
认证响应软件是一个模块化和可扩展的实用软件,旨在便利对包括Web2App,App2App在内的所有支持认证流的智能ID认证响应进行全面的验证,以及传统的后端启动程序.
密钥能力
- Smart-ID认证响应结构和内容的核心验证
- 证书信任链对可配置 CA 商店的核查
- 证书有效期检查
- Smart-ID 方案识别( 最终实体证书) 执行
- 可选证书策略 OID 验证
- 在Web2App和App2App流中与CallbackUrlValidator进行无缝集成,用于对Callback参数进行端到端验证
灵活而可编译的建筑
这个库设计有一个以开发者为中心,以建筑为块的哲学,赋予团队根据项目特定的安全要求来调整其验证逻辑的能力:
- 使用.validate()进行全智能ID响应验证,包括强制ACSP V2签名验证
- 将 . 与 Callback UrlValidate () 合并, 用于全链、 端到端的回调流量验证
- 证书信任链和签名检查总是由.validate()执行,不能省略
示例使用
// Developer-managed location containing trusted CA certificates
// ⚠️ IMPORTANT:
// This library does **not** download or manage CA certificates for you.
// You, as the implementer, must ensure the folder contains the correct, trusted CA certificates
// provided by SK-ID or your organization's security policy.
const resourcesPath = path.resolve(__dirname, "../certificates");
const validator = new AuthenticationResponseValidator(resourcesPath);
// validate() runs the full response check AND ACSP_V2 signature verification:
// session state, end result, certificate presence, certificate trust chain, expiry,
// certificate level, Smart-ID EKU, and the cryptographic ACSP_V2 signature.
// The signature inputs (scheme name, interaction type, flow type) MUST be set before
// validate(); if they are missing, validation fails and no identity is returned.
const result = validator
.withSchemeName('smart-id-demo')
.withInteractionTypeUsed('displayTextAndPIN')
.withFlowType('Web2App')
.withCallbackUrlValidate(callBackValidationEntity)
.validate(authResponse, requestPayload)
.getResult();
if (result.hasError()) {
throw new Error(`Has errors ${JSON.stringify(result.getErrors())} `);
}
// An identity is returned ONLY when every check, including signature verification, passed.
const identity = result.getIdentity();
//Optional validation: Check if the certificate includes any of the allowed policy OIDs (e.g., Qualified Certificates)
const allowOIDs = [
'1.3.6.1.4.1.4146.1.1',
'1.3.6.1.4.1.4146.1.2',
'1.3.6.1.4.1.10015.17.2',
];
const allowPoliciesCheck = validator.checkIfHasAllowedCertificatePolicies(
identity.getCertificate(),
allowOIDs,
);
if (!allowPoliciesCheck) {
throw new Error('The allowPoliciesCheck was not verified.');
}
if (identity) {
console.log(`Given Name: ${identity.getGivenName()}`);
console.log(`Surname: ${identity.getSurName()}`);
console.log(`Document Number: ${identity.getDocumentNumber()}`);
console.log(`Country: ${identity.getCountry()}`);
console.log(`Identity Code: ${identity.getIdentityCode()}`);
console.log(`Identity Number: ${identity.getIdentityNumber()}`);
console.log(`Valid From: ${identity.getValidFrom()}`);
console.log(`Valid To: ${identity.getValidTo()}`);
console.log(`Date of Birth: ${identity.getDateOfBirth()}`);
}
认证响应变量方法
| 方法 | 返回类型 | 说明 |
|---|---|---|
constructor(resourcesPath, debug?) | AuthenticationResponseValidator | 创建校验器, 从提供的路径装入信任的 CA 证书 . |
validate(response, payload) | this | 运行完整响应和证书验证 包括强制性ACSP V2签名验证 (结构,过期,信任链,证书级别,计划检查,签名). 要求数 withSchemeName(), (中文(简体) ), withInteractionTypeUsed() 财务报告和审定财务报表 withFlowType() ; 除非签名验证,否则不返回身份. |
withCallbackUrlValidate(entity) | this | 运行 回调 URL 校验器 用于Web2App/App2App. |
checkIfHasAllowedCertificatePolicies(cert, allowedOids) | boolean | 检查证书是否包含至少一个允许的策略 OID . |
verifySignature(response, payload) | boolean | 对照重建后的有效载荷和证书验证ACSP V2签名. 自动引用的还有 validate()。 。 。 . |
withSchemeName(name) | this | 设置 ACSP V2 有效载荷重建的计划名称 . |
withInteractionTypeUsed(value) | this | 设置用于ACSP V2有效载荷重建的交互类型. |
withBrokeredRpName(name) | this | 设置为ACSP V2有效载荷重建的代理RP名. |
withFlowType(value) | this | 设置ACSP V2有效载荷重建的流量类型. |
buildACSPV2Payload(response, payload) | string | 重建签名检查所需的精确ACSP V2有效载荷串. |
getTrustedCACertificates() | string[] | 返回装入的用于信任验证的 CA 证书文件路径列表 . |
getResult() | AuthenticationResult | 返回包含验证错误和被提取身份的结果. |
页:1
- CA Trust Setup:资源Path应该指向包含可信任的.crt或.pem CA证书的目录或文件.
- 设备Link Flows: 对于Web2App和App2App,在.validate()之前总是使用CallbackUrlValidate()来正确处理回调的URL参数.
- 安全提醒 : 该图书馆协助验证,但不能保证充分的安全。 生产部署应当按照"智能识别安全实施指南"进行补充检查.
强烈建议审查和跟踪 安全实施指南 由SK-eID提供。 指南详细描述了所有关键验证步骤,并提供了确保您智能ID集成的安全性和可靠性的最佳做法.
NB来了! 此库旨在简化整合进程,但 生产系统应认真评估并在必要时补充内在核查逻辑 达到安全标准.
认证身份
这个 AuthenticationIdentity 类代表从智能ID证书中提取的认证用户身份.
它为获取姓名、国家、身份号码和文件细节等核心身份信息提供了便利.
此外,该类还提供了访问原始证书的方法,一个经过适当格式化的PEM版本,以及解析的证书细节,包括主题、发行人和扩展.
此类旨在通过封装身份和证书解析逻辑来简化处理Smart-ID认证结果的过程.
身份财产获取器
| 方法 | 返回类型 | 说明 |
|---|---|---|
getGivenName() | string | 返回给定的名称. |
getSurName() | string | 返回姓氏. |
getIdentityCode() | string | 返回身份代码 . |
getIdentityNumber() | string | 返回身份号码. |
getCountry() | string | 归国. |
getDocumentNumber() | string | 返回文档编号. |
getValidFrom() | string | 返回证书有效性开始 . |
getValidTo() | string | 返回证书有效性结束 . |
getDateOfBirth() | string | 返回出生日期. |
证书方法
| 方法 | 返回类型 | 说明 |
|---|---|---|
getCertificate() | string | 返回原始证书( Base64) . |
getPemCertificate() | string | 以 PEM 格式返回证书. |
getParsedCertificate() | Record<string, any> | undefined | 返回解析对象,发行者,扩展等. |
getRawCertificate() | forge.pki.Certificate | undefined | 返回原始伪造证书对象. |
警卫
这个库为Smart-ID认证流提供了必不可少的安全验证机制. 该系统进行重要检查,以帮助确保智能识别系统反应的完整性、真实性和可信赖性,特别是 网络2App 财务报告和审定财务报表 附录2App 场景.
由本图书馆提供的内建验证
图书馆进行下列外出的安全验证:
-
会话补全检查
- 确保认证会话状态为
"COMPLETE"。 。 。 . - 验证最终认证结果为
"OK"。 。 。 . - 确认存在有效的证书和签名.
- 确保认证会话状态为
-
证书验证
- 解析并验证智能ID最终用户证书.
- 检查证书过期日期 .
- 以信任的 CA 商店验证证书( 本地
.pem或者说.crt文档). - 强制执行 智能识别方案,验证正确的密钥Usage和扩展密钥使用属性.
- 可选验证允许的证书政策 OID
checkIfHasAllowedCertificatePolicies。 。 。 .
-
签字核查
- 根据Smart-ID规格重新构建所签名的有效载荷.
- 使用从最终用户证书中提取的公用钥匙验证签名.
- 支持对两者进行严格的签名检查 网络2App 财务报告和审定财务报表 附录2App 流动.
-
回调 URL 参数验证
- 在召回后验证会话状态和基本响应完整性.
- 验证
sessionSecretDigest诚信. - 验证
userChallengeVerifier与签名的用户挑战值相对应.
QQ 限制和需要的服务器- 单个考虑
虽然这个库涵盖关键的客户端验证,但依赖方(你的服务器应用程序)仍负有下列安全责任:
-
适当储存和管理信任的 CA 证书
- 您必须提供一个有效的,最新的 CA 证书目录,以确保信任验证是有意义的.
- 库不自动更新或获取 CA 证书 .
-
重放攻击保护
- 库不执行服务器侧面机制来防止回放攻击.
- 您必须确保会话符号、 用户挑战和会话机密是单一使用和妥善管理 .
-
严格参数验证
- 任何额外的针对具体业务的验证(如IP白名单,请求来源验证)都不属于本库的范围.
-
后端安全
- 库假定您的服务器侧环境是安全的 .
- 所有敏感材料(会话秘密,中介的"雷克党"名)都必须由你的后端保护.
-
遵守安全实施指南
- 强烈建议您审查并严格遵循 智能ID 安全实施指南。 。 。 .
- 该指南提供了超出图书馆范围的全面建议.
关于证书管理的重要说明
这个图书馆 不单独维护或管理信任的 CA 证书。 。 。 .
您在初始化时必须明确提供您信任的 CA 证书的有效路径 AuthenticationResponseValidator。 。 。 .
你有责任确保:
- CA证书文件完整,正确并定期更新.
- 您的应用程序可以安全访问证书存储位置 .
不提供适当的最新的CA证书将损害信任验证的有效性.
免责声明
这个 独立、第三方、开源库 为方便与官方Smart-ID API集成而开发.
没错 未由 SK ID 解决方案 AS 开发、审查、认可或认证 或任何官方的Smart -ID权威.
提供图书馆 "就这样"没有任何任何形式的保证,无论是明示的还是暗示的.
作者和撰稿人接受 不对任何直接、间接、附带或间接损害负赔偿责任,包括但不限于安全漏洞、数据损失、业务中断或因使用该图书馆而产生的法律后果.
️️️⚠️⚠️⚠️ 使用此图书馆完全由你自己承担风险. ️️️⚠️⚠️⚠️
你有责任确保你的智能身份识别整合完全符合所有适用的法律、条例和官员 智能ID执行准则。 。 。 .
对于生产用途,强烈建议进行彻底的独立审查和采取适当的安全措施.
参考资料
贷项
这个图书馆由黄若瑟发起并维护,社区的贡献受到热烈欢迎. 图书馆在 MIT 许可证免费供个人和商业使用.
许可证
此库在 MIT 许可证。 。 。 .
版权(c)2025-2026 黄若瑟(Joosep Wong)
两者都可以免费使用 商业和非商业 目的,不受超过标准MIT术语的限制.
这个包裹永远不会被许可. 根据《麻省理工学院许可证》,它现在和将来都将永久提供.