App.cs 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380
  1. using Edge.Core.Processor;
  2. using Edge.Core.Processor.Dispatcher.Attributes;
  3. using Edge.Core.UniversalApi;
  4. using Microsoft.Extensions.DependencyInjection;
  5. using Microsoft.Extensions.Logging;
  6. using Microsoft.Extensions.Logging.Abstractions;
  7. using ShengJuDesFireEv1CpuCardKeyLoader;
  8. using System;
  9. using System.Collections.Generic;
  10. using System.Linq;
  11. using System.Text;
  12. using System.Threading.Tasks;
  13. using static ShengJu_CUT100_DES.GroupHandler;
  14. using static ShengJu_CUT100_DES.MessageEntity.Outgoing.ModifyPredefinedFileKey;
  15. namespace ClassicCpuCardApp
  16. {
  17. [UniversalApi(Name = GenericAlarm.UniversalApiEventName, EventDataType = typeof(GenericAlarm[]), Description = "Fire GenericAlarms to AlarmBar for attracting users.")]
  18. [UniversalApi(Name = OnCardTapEventName, EventDataType = typeof(object), Description = "Fired once a DesFire EV1 card detected by module and card UID is read")]
  19. [UniversalApi(Name = OnCardReaderModuleStateChangeEventName, EventDataType = typeof(CardReaderModule), Description = "Fired once card reader module state changed")]
  20. [MetaPartsDescriptor(
  21. "lang-zh-cn:CPU卡读写卡应用lang-en-us:CPU Card Read&Write App",
  22. "lang-zh-cn:CPU卡读写卡应用,用于管理多个 盛炬CUT100_DES 感应卡读写卡模块lang-en-us:CPU卡读写卡应用,用于管理多个 盛炬CUT100_DES 感应卡读写卡模块",
  23. new[] { "lang-zh-cn:支付终端lang-en-us:Terminal" })]
  24. public class App : IAppProcessor
  25. {
  26. private AppConfigV1 appConfig;
  27. private LocalNetworkMacBasedEncryptionKeyLoader keyLoader;
  28. private IEnumerable<ShengJu_CUT100_DES.GroupHandler> cardReaderDeviceHandlers;
  29. private IEnumerable<CardReaderModule> cardReaderModules;
  30. private ILogger logger = NullLogger.Instance;
  31. private IServiceProvider services;
  32. public const string OnCardTapEventName = "OnCardTap";
  33. public const string OnCardReaderModuleStateChangeEventName = "OnCardReaderModuleStateChange";
  34. public string MetaConfigName { get; set; }
  35. public IEnumerable<CardReaderModule> CardReaderModuels => this.cardReaderModules;
  36. public class AppConfigV1
  37. {
  38. public EncryptedBase64KeySet EncryptedBase64KeySet { get; set; }
  39. }
  40. private byte[] blankCardDefaultRootKey;
  41. private byte[] newRootKey;
  42. private byte[] file1DefaultReadKey;
  43. private byte[] file1DefaultWriteKey;
  44. public App(AppConfigV1 appConfig, IServiceProvider services)
  45. {
  46. this.appConfig = appConfig;
  47. this.services = services;
  48. var loggerFactory = services.GetRequiredService<ILoggerFactory>();
  49. this.logger = loggerFactory.CreateLogger("DynamicPrivate_ClassicCpuCardApp");
  50. this.keyLoader = new LocalNetworkMacBasedEncryptionKeyLoader(this.logger);
  51. }
  52. public void Init(IEnumerable<IProcessor> processors)
  53. {
  54. this.cardReaderDeviceHandlers = processors.WithHandlerOrApp<ShengJu_CUT100_DES.GroupHandler>()
  55. .SelectHandlerOrAppThenCast<ShengJu_CUT100_DES.GroupHandler>();
  56. if (this.cardReaderDeviceHandlers == null || !this.cardReaderDeviceHandlers.Any())
  57. throw new InvalidOperationException("当前 APP 的运行必须要求系统中配置一个或者多个“ShengJu_CUT100_DES设备驱动” ,但当前没有获取到,请配置并启用相应设备驱动后重试");
  58. if (this.cardReaderDeviceHandlers.SelectMany(dh => dh.CardReaderModuels).GroupBy(b => new { b.UnderlyingCommunicatorIdentity, b.PhysicalAddress }).Any(g => g.Count() >= 2))
  59. throw new ArgumentException("发现多个 'ShengJu_CUT100_DES设备驱动' 配置中有重复的硬件地址值,请检查相应的设备驱动以确保同一通讯链路上硬件地址唯一,再重试 ");
  60. if (this.cardReaderDeviceHandlers.SelectMany(dh => dh.CardReaderModuels).GroupBy(b => b.Name).Any(g => g.Count() >= 2))
  61. throw new ArgumentException("发现多个 'ShengJu_CUT100_DES设备驱动' 配置中有重复的读卡器名称(Name),请检查相应的设备驱动以确保全局名称唯一,再重试 ");
  62. foreach (var dh in this.cardReaderDeviceHandlers)
  63. {
  64. dh.OnModuleStateChange += async (s, a) =>
  65. {
  66. var universalApiHub = this.services.GetRequiredService<UniversalApiHub>();
  67. await universalApiHub?.FireEvent(this, OnCardReaderModuleStateChangeEventName, dh);
  68. };
  69. }
  70. foreach (var dh in this.cardReaderDeviceHandlers)
  71. {
  72. dh.OnCardTap += async (s, a) =>
  73. {
  74. var universalApiHub = this.services.GetRequiredService<UniversalApiHub>();
  75. await universalApiHub?.FireEvent(this, OnCardTapEventName, a);
  76. };
  77. }
  78. this.cardReaderModules = this.cardReaderDeviceHandlers.SelectMany(dh => dh.CardReaderModuels);
  79. }
  80. [UniversalApi(Description = "Get all available card reader moduel names")]
  81. public async Task<IEnumerable<CardReaderModule>> GetCardReaderModuleNames()
  82. {
  83. return this.cardReaderDeviceHandlers.SelectMany(dh => dh.CardReaderModuels);
  84. }
  85. [UniversalApi(
  86. Description = "Set new RootKey to card, re-build(clear, re-create and set file keys) the files and blocks(4 files, and 4 blocks with 32 bytes for each file).</br>" +
  87. "All the new keys are <b>decrypted</b> from app's config values.</br>" +
  88. "Leave oldRootKeyBytes to <b>null</b> will use the key decrypted from app's config values.</br>" +
  89. "For most DesFireEV1 Cards, the <b>factory-reset</b> root and file read&write keys are 16 bytes of 0</br>",
  90. InputParametersExampleJson = "[\"desktopReader0\",[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]]")]
  91. public async Task<IEnumerable<CardOperationResult>> FormatCard(string cardReaderModuleName, int[] oldRootKeyBytes)
  92. {
  93. var keySet = this.keyLoader.Get(this.appConfig.EncryptedBase64KeySet);
  94. if (oldRootKeyBytes == null)
  95. oldRootKeyBytes = keySet.RootKey.Select(b => (int)b).ToArray();
  96. var formatBatchOperationTasks = this.cardReaderDeviceHandlers.Select(h =>
  97. h.FormatCardByResetToNewRootKeyAndBuildDefaultFileStructures(cardReaderModuleName,
  98. oldRootKeyBytes.Select(i => (byte)i).ToArray(),
  99. keySet.RootKey));
  100. var formatResultsRaw = await Task.WhenAll(formatBatchOperationTasks);
  101. var formatResults = formatResultsRaw.SelectMany(r => r);
  102. if (formatResults.Any(r => r.OverallResultCode != 200))
  103. return formatResults;
  104. //if (!setFileKeys)
  105. // return formatResults;
  106. byte[] oldFileKeyBytes = Enumerable.Repeat(0, 16).Select(i => (byte)i).ToArray();
  107. //文件1
  108. byte[] fileKey = keySet.文件1读密钥;
  109. var modifyPredefinedFileKeybatchOperationTasks = this.cardReaderDeviceHandlers.Select(h =>
  110. h.ModifyPredefinedFileKey(cardReaderModuleName,
  111. PredefinedFileKeyTypeEnum.文件1读密钥, oldFileKeyBytes, fileKey));
  112. var modifyPredefinedFileKeyResultsRaw = await Task.WhenAll(modifyPredefinedFileKeybatchOperationTasks);
  113. var modifyPredefinedFileKeyResults = modifyPredefinedFileKeyResultsRaw.SelectMany(r => r);
  114. if (modifyPredefinedFileKeyResults.Any(r => r.OverallResultCode != 200))
  115. return modifyPredefinedFileKeyResults;
  116. fileKey = keySet.文件1读写密钥;
  117. modifyPredefinedFileKeybatchOperationTasks = this.cardReaderDeviceHandlers.Select(h =>
  118. h.ModifyPredefinedFileKey(cardReaderModuleName,
  119. PredefinedFileKeyTypeEnum.文件1读写密钥, oldFileKeyBytes, fileKey));
  120. modifyPredefinedFileKeyResultsRaw = await Task.WhenAll(modifyPredefinedFileKeybatchOperationTasks);
  121. modifyPredefinedFileKeyResults = modifyPredefinedFileKeyResultsRaw.SelectMany(r => r);
  122. if (modifyPredefinedFileKeyResults.Any(r => r.OverallResultCode != 200))
  123. return modifyPredefinedFileKeyResults;
  124. //文件2
  125. fileKey = keySet.文件2读密钥;
  126. modifyPredefinedFileKeybatchOperationTasks = this.cardReaderDeviceHandlers.Select(h =>
  127. h.ModifyPredefinedFileKey(cardReaderModuleName,
  128. PredefinedFileKeyTypeEnum.文件2读密钥, oldFileKeyBytes, fileKey));
  129. modifyPredefinedFileKeyResultsRaw = await Task.WhenAll(modifyPredefinedFileKeybatchOperationTasks);
  130. modifyPredefinedFileKeyResults = modifyPredefinedFileKeyResultsRaw.SelectMany(r => r);
  131. if (modifyPredefinedFileKeyResults.Any(r => r.OverallResultCode != 200))
  132. return modifyPredefinedFileKeyResults;
  133. fileKey = keySet.文件2读写密钥;
  134. modifyPredefinedFileKeybatchOperationTasks = this.cardReaderDeviceHandlers.Select(h =>
  135. h.ModifyPredefinedFileKey(cardReaderModuleName,
  136. PredefinedFileKeyTypeEnum.文件2读写密钥, oldFileKeyBytes, fileKey));
  137. modifyPredefinedFileKeyResultsRaw = await Task.WhenAll(modifyPredefinedFileKeybatchOperationTasks);
  138. modifyPredefinedFileKeyResults = modifyPredefinedFileKeyResultsRaw.SelectMany(r => r);
  139. if (modifyPredefinedFileKeyResults.Any(r => r.OverallResultCode != 200))
  140. return modifyPredefinedFileKeyResults;
  141. //文件3
  142. fileKey = keySet.文件3读密钥;
  143. modifyPredefinedFileKeybatchOperationTasks = this.cardReaderDeviceHandlers.Select(h =>
  144. h.ModifyPredefinedFileKey(cardReaderModuleName,
  145. PredefinedFileKeyTypeEnum.文件3读密钥, oldFileKeyBytes, fileKey));
  146. modifyPredefinedFileKeyResultsRaw = await Task.WhenAll(modifyPredefinedFileKeybatchOperationTasks);
  147. modifyPredefinedFileKeyResults = modifyPredefinedFileKeyResultsRaw.SelectMany(r => r);
  148. if (modifyPredefinedFileKeyResults.Any(r => r.OverallResultCode != 200))
  149. return modifyPredefinedFileKeyResults;
  150. fileKey = keySet.文件3读写密钥;
  151. modifyPredefinedFileKeybatchOperationTasks = this.cardReaderDeviceHandlers.Select(h =>
  152. h.ModifyPredefinedFileKey(cardReaderModuleName,
  153. PredefinedFileKeyTypeEnum.文件3读写密钥, oldFileKeyBytes, fileKey));
  154. modifyPredefinedFileKeyResultsRaw = await Task.WhenAll(modifyPredefinedFileKeybatchOperationTasks);
  155. modifyPredefinedFileKeyResults = modifyPredefinedFileKeyResultsRaw.SelectMany(r => r);
  156. if (modifyPredefinedFileKeyResults.Any(r => r.OverallResultCode != 200))
  157. return modifyPredefinedFileKeyResults;
  158. //文件4
  159. fileKey = keySet.文件4读密钥;
  160. modifyPredefinedFileKeybatchOperationTasks = this.cardReaderDeviceHandlers.Select(h =>
  161. h.ModifyPredefinedFileKey(cardReaderModuleName,
  162. PredefinedFileKeyTypeEnum.文件4读密钥, oldFileKeyBytes, fileKey));
  163. modifyPredefinedFileKeyResultsRaw = await Task.WhenAll(modifyPredefinedFileKeybatchOperationTasks);
  164. modifyPredefinedFileKeyResults = modifyPredefinedFileKeyResultsRaw.SelectMany(r => r);
  165. if (modifyPredefinedFileKeyResults.Any(r => r.OverallResultCode != 200))
  166. return modifyPredefinedFileKeyResults;
  167. fileKey = keySet.文件4读写密钥;
  168. modifyPredefinedFileKeybatchOperationTasks = this.cardReaderDeviceHandlers.Select(h =>
  169. h.ModifyPredefinedFileKey(cardReaderModuleName,
  170. PredefinedFileKeyTypeEnum.文件4读写密钥, oldFileKeyBytes, fileKey));
  171. modifyPredefinedFileKeyResultsRaw = await Task.WhenAll(modifyPredefinedFileKeybatchOperationTasks);
  172. modifyPredefinedFileKeyResults = modifyPredefinedFileKeyResultsRaw.SelectMany(r => r);
  173. if (modifyPredefinedFileKeyResults.Any(r => r.OverallResultCode != 200))
  174. return modifyPredefinedFileKeyResults;
  175. return modifyPredefinedFileKeyResults;
  176. }
  177. [UniversalApi(
  178. Description = "Modify the read or write keys for the specified file, the new key is decrypted from app's config values, " +
  179. "make sure adding those enctryption keys from config UI first.",
  180. InputParametersExampleJson = "[\"desktopReader0\",\"文件1读密钥\",[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]]")]
  181. public async Task<CardOperationResult[]> ModifyPredefinedFileKey(string cardReaderModuleName, PredefinedFileKeyTypeEnum fileKeyType, int[] oldKeyBytes)
  182. {
  183. var keySet = this.keyLoader.Get(this.appConfig.EncryptedBase64KeySet);
  184. byte[] newKey = null;
  185. if (fileKeyType == PredefinedFileKeyTypeEnum.根密钥)
  186. newKey = keySet.文件1读密钥;
  187. if (fileKeyType == PredefinedFileKeyTypeEnum.文件1读密钥)
  188. newKey = keySet.文件1读密钥;
  189. if (fileKeyType == PredefinedFileKeyTypeEnum.文件1读写密钥)
  190. newKey = keySet.文件1读写密钥;
  191. if (fileKeyType == PredefinedFileKeyTypeEnum.文件2读密钥)
  192. newKey = keySet.文件2读密钥;
  193. if (fileKeyType == PredefinedFileKeyTypeEnum.文件2读写密钥)
  194. newKey = keySet.文件2读写密钥;
  195. if (fileKeyType == PredefinedFileKeyTypeEnum.文件3读密钥)
  196. newKey = keySet.文件3读密钥;
  197. if (fileKeyType == PredefinedFileKeyTypeEnum.文件3读写密钥)
  198. newKey = keySet.文件3读写密钥;
  199. if (fileKeyType == PredefinedFileKeyTypeEnum.文件4读密钥)
  200. newKey = keySet.文件4读密钥;
  201. if (fileKeyType == PredefinedFileKeyTypeEnum.文件4读写密钥)
  202. newKey = keySet.文件4读写密钥;
  203. if ((oldKeyBytes?.Length ?? 0) != 16)
  204. throw new ArgumentOutOfRangeException(nameof(oldKeyBytes));
  205. var batchOperationTasks = this.cardReaderDeviceHandlers.Select(h =>
  206. h.ModifyPredefinedFileKey(cardReaderModuleName, fileKeyType, oldKeyBytes.Select(i => (byte)i).ToArray(), newKey));
  207. var results = await Task.WhenAll(batchOperationTasks);
  208. List<CardOperationResult> final = new List<CardOperationResult>();
  209. foreach (var r in results)
  210. final.AddRange(r);
  211. return final.ToArray();
  212. }
  213. [UniversalApi(Description = "Write a 32 bytes content to card by specify the destination fileId and blockAddress, " +
  214. "the default fileId range is from 1 to 4, with 4 blocks in a file with address from 1-4, each block with size 32 bytes.",
  215. InputParametersExampleJson = "[\"desktopReader0\",1,1,[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32]]")]
  216. public async Task<CardOperationResult[]> WriteCardWithRawData(string cardReaderModuleName, byte fileId, byte blockAddress, int[] dataBytes)
  217. {
  218. var keySet = this.keyLoader.Get(this.appConfig.EncryptedBase64KeySet);
  219. byte[] writeKey = null;
  220. if (fileId == 1)
  221. writeKey = keySet.文件1读写密钥;
  222. else if (fileId == 2)
  223. writeKey = keySet.文件2读写密钥;
  224. else if (fileId == 3)
  225. writeKey = keySet.文件3读写密钥;
  226. else if (fileId == 4)
  227. writeKey = keySet.文件4读写密钥;
  228. else
  229. throw new ArgumentOutOfRangeException(nameof(fileId));
  230. if (blockAddress == 0 || blockAddress > 4)
  231. throw new ArgumentOutOfRangeException(nameof(blockAddress));
  232. if ((dataBytes?.Length ?? 0) != 32)
  233. throw new ArgumentOutOfRangeException(nameof(dataBytes));
  234. var batchOperationTasks = this.cardReaderDeviceHandlers.Select(h =>
  235. h.WriteCard(cardReaderModuleName, fileId, blockAddress, dataBytes.Select(i => (byte)i).ToArray(), writeKey));
  236. var results = await Task.WhenAll(batchOperationTasks);
  237. List<CardOperationResult> final = new List<CardOperationResult>();
  238. foreach (var r in results)
  239. final.AddRange(r);
  240. return final.ToArray();
  241. }
  242. [UniversalApi(Description = "Write a text content (which must have Utf8 bytes length <=32) to card by specify the destination fileId and blockAddress, " +
  243. "the default fileId range is from 1 to 4, with 4 blocks in a file with address from 1-4, each block with size 32 bytes.",
  244. InputParametersExampleJson = "[\"desktopReader0\",1,1,\"UserNameIsShao\"]")]
  245. public async Task<CardOperationResult[]> WriteCardWithTextData(string cardReaderModuleName, byte fileId, byte blockAddress, string plainTextData)
  246. {
  247. var keySet = this.keyLoader.Get(this.appConfig.EncryptedBase64KeySet);
  248. byte[] writeKey = null;
  249. if (fileId == 1)
  250. writeKey = keySet.文件1读写密钥;
  251. else if (fileId == 2)
  252. writeKey = keySet.文件2读写密钥;
  253. else if (fileId == 3)
  254. writeKey = keySet.文件3读写密钥;
  255. else if (fileId == 4)
  256. writeKey = keySet.文件4读写密钥;
  257. else
  258. throw new ArgumentOutOfRangeException(nameof(fileId));
  259. if (blockAddress == 0 || blockAddress > 4)
  260. throw new ArgumentOutOfRangeException(nameof(blockAddress));
  261. var dataBytes = Encoding.UTF8.GetBytes(plainTextData);
  262. if ((dataBytes?.Length ?? 0) > 32)
  263. throw new ArgumentOutOfRangeException(nameof(dataBytes));
  264. char paddingRightChar = ' ';
  265. dataBytes = dataBytes.Concat(Enumerable.Repeat((byte)paddingRightChar, 32 - dataBytes.Length)).ToArray();
  266. var batchOperationTasks = this.cardReaderDeviceHandlers.Select(h =>
  267. h.WriteCard(cardReaderModuleName, fileId, blockAddress, dataBytes, writeKey));
  268. var results = await Task.WhenAll(batchOperationTasks);
  269. List<CardOperationResult> final = new List<CardOperationResult>();
  270. foreach (var r in results)
  271. final.AddRange(r);
  272. return final.ToArray();
  273. }
  274. [UniversalApi(Description = "Read a 32 bytes content from card by specify the source fileId and blockAddress, " +
  275. "the default fileId range is from 1 to 4, with 4 blocks in a file with address from 1-4, each block with size 32 bytes.",
  276. InputParametersExampleJson = "[\"desktopReader0\",1,1]")]
  277. public async Task<CardOperationResult[]> ReadCardContent(string cardReaderModuleName, byte fileId, byte blockAddress)
  278. {
  279. var keySet = this.keyLoader.Get(this.appConfig.EncryptedBase64KeySet);
  280. byte[] readKey = null;
  281. if (fileId == 1)
  282. readKey = keySet.文件1读密钥;
  283. else if (fileId == 2)
  284. readKey = keySet.文件2读密钥;
  285. else if (fileId == 3)
  286. readKey = keySet.文件3读密钥;
  287. else if (fileId == 4)
  288. readKey = keySet.文件4读密钥;
  289. else
  290. throw new ArgumentOutOfRangeException(nameof(fileId));
  291. if (blockAddress == 0 || blockAddress > 4)
  292. throw new ArgumentOutOfRangeException(nameof(blockAddress));
  293. var batchOperationTasks = this.cardReaderDeviceHandlers.Select(h =>
  294. h.ReadCard(cardReaderModuleName, fileId, blockAddress, readKey));
  295. var results = await Task.WhenAll(batchOperationTasks);
  296. List<CardOperationResult> final = new List<CardOperationResult>();
  297. foreach (var r in results)
  298. final.AddRange(r);
  299. return final.ToArray();
  300. }
  301. [UniversalApi(Description = "Read card open ID(unsafe) from any card tapped on card reader module(s).",
  302. InputParametersExampleJson = "[\"desktopReader0\"]")]
  303. public async Task<CardOperationResult[]> ReadCardID(string cardReaderModuleName)
  304. {
  305. var batchOperationTasks = this.cardReaderDeviceHandlers.Select(h =>
  306. h.ReadCardUID(cardReaderModuleName));
  307. var results = await Task.WhenAll(batchOperationTasks);
  308. List<CardOperationResult> final = new List<CardOperationResult>();
  309. foreach (var r in results)
  310. final.AddRange(r);
  311. return final.ToArray();
  312. }
  313. [UniversalApi(Description = "Input the plain text key, it'll get encrypted and output a encrypted base64 encoded key which can be safely distributed.")]
  314. public async Task<string> GenerateLocalEncryptedBase64Key(string plainTextKey)
  315. {
  316. return this.keyLoader.EncryptStringToBase64(plainTextKey);
  317. }
  318. //[UniversalApi(Description = "Input the encryptedBase64Key, and it'll get decrypted with a result of int array.")]
  319. //public async Task<int[]> DecryptedBase64Key(string encryptedBase64Key)
  320. //{
  321. // return this.keyLoader.Decrypt(Convert.FromBase64String(encryptedBase64Key)).Select(b => (int)b).ToArray();
  322. //}
  323. [UniversalApi(Description = "Input the plain key set, it'll get encrypted and output a encrypted base64 encoded keyset which can be safely distributed.")]
  324. public async Task<EncryptedBase64KeySet> GenerateLocalEncryptedBase64KeySet(InputBase64PlainKeySet plainKeySet)
  325. {
  326. var output = new EncryptedBase64KeySet();
  327. output.RootKey = this.keyLoader.EncryptStringToBase64(plainKeySet.RootKey);
  328. output.文件1读写密钥 = this.keyLoader.EncryptStringToBase64(plainKeySet.文件1读写密钥);
  329. output.文件1读密钥 = this.keyLoader.EncryptStringToBase64(plainKeySet.文件1读密钥);
  330. output.文件2读写密钥 = this.keyLoader.EncryptStringToBase64(plainKeySet.文件2读写密钥);
  331. output.文件2读密钥 = this.keyLoader.EncryptStringToBase64(plainKeySet.文件2读密钥);
  332. output.文件3读写密钥 = this.keyLoader.EncryptStringToBase64(plainKeySet.文件3读写密钥);
  333. output.文件3读密钥 = this.keyLoader.EncryptStringToBase64(plainKeySet.文件3读密钥);
  334. output.文件4读写密钥 = this.keyLoader.EncryptStringToBase64(plainKeySet.文件4读写密钥);
  335. output.文件4读密钥 = this.keyLoader.EncryptStringToBase64(plainKeySet.文件4读密钥);
  336. output.Description = plainKeySet.Description;
  337. return output;
  338. }
  339. }
  340. }