首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何与读者一起检索CAC/智能卡信息?

如何与读者一起检索CAC/智能卡信息?
EN

Stack Overflow用户
提问于 2022-04-26 08:44:47
回答 1查看 633关注 0票数 -1

我在海军陆战队,并试图建立一个数据库来管理一个军械库的MS Access和SharePoint列表。我需要增加新的人,当他们向我报到时,我可以立即给他们分配武器。手动输入他们的信息是很酷的,但是他们有一个CAC/智能卡,上面有所有这些信息,我想看看我是否可以自动完成这个步骤。

有一个ActivClient代理应用程序,我可以打开和查看我的所有信息。有一个叫做“我的个人信息”的部分,它有两个标签,上面有我想要得到的数据(名字,中间,最后,分支,排名,EDIPI)。最近我了解到VBA可以使用Windows (我也刚刚了解到这些API是存在的)。我面临的问题是如何使用安装在政府计算机上的资源来访问CAC信息。我们不能在这些计算机上下载任何工具或库,它必须已经安装。

我发现winscard.h .h有一些函数看起来很有用,但我不知道如何使用它们。我可以使用winscord.h函数来访问和读取连接到我的计算机的第二个CAC的数据吗?我是否应该找到一种不同的方法,比如制作我自己的.dll,它的功能可以完成我需要的所有功能?我学习编程已经有一段时间了,但是当谈到像这样的小众话题时,我不知道如何用最好的方法来解决这个问题。

通常的步骤是:用户使用CAC登录到计算机,打开Access数据库,导航到签入表单,将新连接的卡片插入到第二个读卡器中,以某种方式从卡片中获取数据,用新的数据自动填充表单,然后完成我做的任何事情。我坚持的步骤是严格地从卡中获取数据。

操作系统:仅Windows 10

软件: MS Access 32和64位

硬件:任何智能卡读卡器。我计划和很多人分享这个软件,除了政府的电脑之外,他们没有相同的设备。大多数计算机都有内置的读取器,有时它们可能有独立的读取器或内置阅读器的键盘。

或者,是否更容易获得扫描仪和扫描卡上的条形码?我相信条形码会有我需要的同样的信息。直到我能获得扫描仪的使用许可,我仍然想尝试使用第二个智能卡阅读器,因为这是我现在有。ActivClient或它的资源可以做什么吗?它使用ac.scapi.scmd.dll、acpkcs211.dll、acbsi21.dll和acpivapi.dll。我找不到这些东西的文档。似乎它们中的一个或全部都可以用来获取我想要的数据。

编辑:

我遵循了注释中共享的一些链接,并有以下代码:

代码语言:javascript
运行
复制
Option Explicit
Option Compare Database

Public AuthDict As Scripting.Dictionary
Public Const SCARD_SCOPE_USER As Long = &H0
Public Const SCARD_SCOPE_SYSTEM As Long = &H2
Public Const SCARD_SHARE_SHARED As Long = &H2
Public Const SCARD_SHARE_EXCLUSIVE As Long = &H1
Public Const SCARD_SHARE_DIRECT As Long = &H3
Public Const SCARD_PROTOCOL_T0 As Long = &H1
Public Const SCARD_PROTOCOL_T1 As Long = &H2
Public Const SCARD_DEFAULT_READERS As String = "SCard$DefaultReaders\000"
Public Const SCARD_ALL_READERS As String = "SCard$AllReaders\000"

Public Declare PtrSafe Function SCardEstablishContext Lib "winscard.dll" ( _
    ByVal dwScope As Long, _
    ByVal pvReserved1 As LongPtr, _
    ByVal pvReserved2 As LongPtr, _
    ByRef phContext As LongPtr _
    ) As Long

Public Declare PtrSafe Function SCardIsValidContext Lib "winscard.dll" ( _
    ByVal hContext As LongPtr _
) As Long

Public Declare PtrSafe Function SCardReleaseContext Lib "winscard.dll" ( _
    ByVal hContext As LongPtr) As Long
    
Public Declare PtrSafe Function SCardConnectA Lib "winscard.dll" ( _
    ByVal hContext As LongPtr, _
    szReader As LongPtr, _
    dwShareMode As LongPtr, _
    dwPreferredProtocols As LongPtr, _
    phCard As LongPtr, _
    pdwActiveProtocol) As LongPtr

Public Function SCardAuthCode(lReturn As Long)
'Credit: https://stackoverflow.com/questions/67199032/access-vba-and-smart-cards-whats-the-trick
AuthDict.RemoveAll
Dim hreturn As String, hc As String, hd As String
hreturn = "0x" & Right("0000000" & Hex(lReturn), 8)

Select Case hreturn
    Case "0x00000000": hc = "SCARD_S_SUCCESS": hd = "No error was encountered."
    Case "0x00000006": hc = "ERROR_INVALID_HANDLE": hd = "The handle is invalid."
    Case "0x00000109": hc = "ERROR_BROKEN_PIPE": hd = "The client attempted a smart card operation in a remote session, such as a client session running on a terminal server, and the operating system in use does not support smart card redirection."
    Case "0x80100001": hc = "SCARD_F_INTERNAL_ERROR": hd = "An internal consistency check failed."
    Case "0x80100002": hc = "SCARD_E_CANCELLED": hd = "The action was canceled by an SCardCancel request."
    Case "0x80100003": hc = "SCARD_E_INVALID_HANDLE": hd = "The supplied handle was not valid."
    Case "0x80100004": hc = "SCARD_E_INVALID_PARAMETER": hd = "One or more of the supplied parameters could not be properly interpreted."
    Case "0x80100005": hc = "SCARD_E_INVALID_TARGET": hd = "Registry startup information is missing or not valid."
    Case "0x80100006": hc = "SCARD_E_NO_MEMORY": hd = "Not enough memory available to complete this command."
    Case "0x80100007": hc = "SCARD_F_WAITED_TOO_LONG": hd = "An internal consistency timer has expired."
    Case "0x80100008": hc = "SCARD_E_INSUFFICIENT_BUFFER": hd = "The data buffer for returned data is too small for the returned data."
    Case "0x80100009": hc = "SCARD_E_UNKNOWN_READER": hd = "The specified reader name is not recognized."
    Case "0x8010000A": hc = "SCARD_E_TIMEOUT": hd = "The user-specified time-out value has expired."
    Case "0x8010000B": hc = "SCARD_E_SHARING_VIOLATION": hd = "The smart card cannot be accessed because of other outstanding connections."
    Case "0x8010000C": hc = "SCARD_E_NO_SMARTCARD": hd = "The operation requires a smart card, but no smart card is currently in the device."
    Case "0x8010000D": hc = "SCARD_E_UNKNOWN_CARD": hd = "The specified smart card name is not recognized."
    Case "0x8010000E": hc = "SCARD_E_CANT_DISPOSE": hd = "The system could not dispose of the media in the requested manner."
    Case "0x8010000F": hc = "SCARD_E_PROTO_MISMATCH": hd = "The requested protocols are incompatible with the protocol currently in use with the card."
    Case "0x80100010": hc = "SCARD_E_NOT_READY": hd = "The reader or card is not ready to accept commands."
    Case "0x80100011": hc = "SCARD_E_INVALID_VALUE": hd = "One or more of the supplied parameter values could not be properly interpreted."
    Case "0x80100012": hc = "SCARD_E_SYSTEM_CANCELLED": hd = "The action was canceled by the system, presumably to log off or shut down."
    Case "0x80100013": hc = "SCARD_F_COMM_ERROR": hd = "An internal communications error has been detected."
    Case "0x80100014": hc = "SCARD_F_UNKNOWN_ERROR": hd = "An internal error has been detected, but the source is unknown."
    Case "0x80100015": hc = "SCARD_E_INVALID_ATR": hd = "An ATR string obtained from the registry is not a valid ATR string."
    Case "0x80100016": hc = "SCARD_E_NOT_TRANSACTED": hd = "An attempt was made to end a nonexistent transaction."
    Case "0x80100017": hc = "SCARD_E_READER_UNAVAILABLE": hd = "The specified reader is not currently available for use."
    Case "0x80100018": hc = "SCARD_P_SHUTDOWN": hd = "The operation has been aborted to allow the server application to exit."
    Case "0x80100019": hc = "SCARD_E_PCI_TOO_SMALL": hd = "The PCI receive buffer was too small."
    Case "0x8010001A": hc = "SCARD_E_READER_UNSUPPORTED": hd = "The reader driver does not meet minimal requirements for support."
    Case "0x8010001B": hc = "SCARD_E_DUPLICATE_READER": hd = "The reader driver did not produce a unique reader name."
    Case "0x8010001C": hc = "SCARD_E_CARD_UNSUPPORTED": hd = "The smart card does not meet minimal requirements for support."
    Case "0x8010001D": hc = "SCARD_E_NO_SERVICE": hd = "The smart card resource manager is not running."
    Case "0x8010001E": hc = "SCARD_E_SERVICE_STOPPED": hd = "The smart card resource manager has shut down."
    Case "0x8010001F": hc = "SCARD_E_UNEXPECTED": hd = "An unexpected card error has occurred."
    Case "0x80100020": hc = "SCARD_E_ICC_INSTALLATION": hd = "No primary provider can be found for the smart card."
    Case "0x80100021": hc = "SCARD_E_ICC_CREATEORDER": hd = "The requested order of object creation is not supported."
    Case "0x80100022": hc = "SCARD_E_UNSUPPORTED_FEATURE": hd = "This smart card does not support the requested feature."
    Case "0x80100023": hc = "SCARD_E_DIR_NOT_FOUND": hd = "The specified directory does not exist in the smart card."
    Case "0x80100024": hc = "SCARD_E_FILE_NOT_FOUND": hd = "The specified file does not exist in the smart card."
    Case "0x80100025": hc = "SCARD_E_NO_DIR": hd = "The supplied path does not represent a smart card directory."
    Case "0x80100026": hc = "SCARD_E_NO_FILE": hd = "The supplied path does not represent a smart card file."
    Case "0x80100027": hc = "SCARD_E_NO_ACCESS": hd = "Access is denied to the file."
    Case "0x80100028": hc = "SCARD_E_WRITE_TOO_MANY": hd = "An attempt was made to write more data than would fit in the target object."
    Case "0x80100029": hc = "SCARD_E_BAD_SEEK": hd = "An error occurred in setting the smart card file object pointer."
    Case "0x8010002A": hc = "SCARD_E_INVALID_CHV": hd = "The supplied PIN is incorrect."
    Case "0x8010002B": hc = "SCARD_E_UNKNOWN_RES_MNG": hd = "An unrecognized error code was returned."
    Case "0x8010002C": hc = "SCARD_E_NO_SUCH_CERTIFICATE": hd = "The requested certificate does not exist."
    Case "0x8010002D": hc = "SCARD_E_CERTIFICATE_UNAVAILABLE": hd = "The requested certificate could not be obtained."
    Case "0x8010002E": hc = "SCARD_E_NO_READERS_AVAILABLE": hd = "No smart card reader is available."
    Case "0x8010002F": hc = "SCARD_E_COMM_DATA_LOST": hd = "A communications error with the smart card has been detected."
    Case "0x80100030": hc = "SCARD_E_NO_KEY_CONTAINER": hd = "The requested key container does not exist on the smart card."
    Case "0x80100031": hc = "SCARD_E_SERVER_TOO_BUSY": hd = "The smart card resource manager is too busy to complete this operation."
    Case "0x80100032": hc = "SCARD_E_PIN_CACHE_EXPIRED": hd = "The smart card PIN cache has expired."
    Case "0x80100033": hc = "SCARD_E_NO_PIN_CACHE": hd = "The smart card PIN cannot be cached."
    Case "0x80100034": hc = "SCARD_E_READ_ONLY_CARD": hd = "The smart card is read-only and cannot be written to."
    Case "0x80100065": hc = "SCARD_W_UNSUPPORTED_CARD": hd = "The reader cannot communicate with the card, due to ATR string configuration conflicts."
    Case "0x80100066": hc = "SCARD_W_UNRESPONSIVE_CARD": hd = "The smart card is not responding to a reset."
    Case "0x80100067": hc = "SCARD_W_UNPOWERED_CARD": hd = "Power has been removed from the smart card, so that further communication is not possible."
    Case "0x80100068": hc = "SCARD_W_RESET_CARD": hd = "The smart card was reset."
    Case "0x80100069": hc = "SCARD_W_REMOVED_CARD": hd = "The smart card has been removed, so further communication is not possible."
    Case "0x8010006A": hc = "SCARD_W_SECURITY_VIOLATION": hd = "Access was denied because of a security violation."
    Case "0x8010006B": hc = "SCARD_W_WRONG_CHV": hd = "The card cannot be accessed because the wrong PIN was presented."
    Case "0x8010006C": hc = "SCARD_W_CHV_BLOCKED": hd = "The card cannot be accessed because the maximum number of PIN entry attempts has been reached."
    Case "0x8010006D": hc = "SCARD_W_EOF": hd = "The end of the smart card file has been reached."
    Case "0x8010006E": hc = "SCARD_W_CANCELLED_BY_USER": hd = "The action was canceled by the user."
    Case "0x8010006F": hc = "SCARD_W_CARD_NOT_AUTHENTICATED": hd = "No PIN was presented to the smart card."
    Case "0x80100070": hc = "SCARD_W_CACHE_ITEM_NOT_FOUND": hd = "The requested item could not be found in the cache."
    Case "0x80100071": hc = "SCARD_W_CACHE_ITEM_STALE": hd = "The requested cache item is too old and was deleted from the cache."
    Case "0x80100072": hc = "SCARD_W_CACHE_ITEM_TOO_BIG": hd = "The new cache item exceeds the maximum per-item size defined for the cache."
    Case Else: hc = "UNKNOWN VALUE": hd = "Unknown value."
End Select

AuthDict.Add "hr", hreturn
AuthDict.Add "hc", hc
AuthDict.Add "hd", hd
End Function

Public Sub GetContext()
'https://learn.microsoft.com/en-us/windows/win32/secauthn/authentication-return-values?redirectedfrom=MSDN#smart_card_return_values
'https://learn.microsoft.com/en-us/windows/win32/debug/system-error-codes--0-499-?redirectedfrom=MSDN
'Credit: https://stackoverflow.com/questions/67199032/access-vba-and-smart-cards-whats-the-trick

'TODO: Finish SCardConnectA

Dim lReturn As Long
Dim RSVD1 As Long, RSVD2 As Long
Dim myContext, cardCon As LongPtr
Set AuthDict = New Scripting.Dictionary

Debug.Print "-----------------------------------------------------------------------------"

lReturn = SCardEstablishContext(SCARD_SCOPE_USER, RSVD1, RSVD2, myContext)
SCardAuthCode lReturn
Debug.Print "SCardEstablishContext:" & vbCrLf & _
    "   Return = " & AuthDict("hr") & vbCrLf & _
    "   Value = " & AuthDict("hc") & vbCrLf & _
    "   Description = " & AuthDict("hd") & vbCrLf
    
lReturn = SCardIsValidContext(myContext)
SCardAuthCode lReturn
Debug.Print "SCardIsValidContext:" & vbCrLf & _
    "   Return = " & AuthDict("hr") & vbCrLf & _
    "   Value = " & AuthDict("hc") & vbCrLf & _
    "   Description = " & AuthDict("hd") & vbCrLf

If lReturn <> 0 Then GoTo GetContextExit

GetContextExit:
    Debug.Print "-----------------------------------------------------------------------------" & vbCrLf
    SCardReleaseContext myContext
    Exit Sub
    
ErrorHandler:
    'TODO: handle the errors...
    Resume GetContextExit
    
End Sub

我不知道有什么意义

代码语言:javascript
运行
复制
Public Type SCARDCONTEXT
    CardContext1 As Long
    ReaderName As String
End Type

在我所遵循的代码中。它导致了我的错误,所以我就把它删除了。代码输出

代码语言:javascript
运行
复制
-----------------------------------------------------------------------------
SCardEstablishContext:
   Return = 0x00000000
   Value = SCARD_S_SUCCESS
   Description = No error was encountered.

SCardIsValidContext:
   Return = 0x00000000
   Value = SCARD_S_SUCCESS
   Description = No error was encountered.

-----------------------------------------------------------------------------

我不太确定下一步该做什么。现在我似乎需要识别我想要的数据的名称(GetOpenCardNameA?),连接到它(SCardConnectA),然后使用SCardTransmit从卡接收数据?我不确定这些功能是否就是这样运作的。

EN

Stack Overflow用户

发布于 2022-04-26 22:15:14

不是100%确定你是否能得到这样的CAC信息,但我知道大多数空军CTK程序都使用具有CAC功能的TCMax,而且你可以100%地设置它以供军械库使用,并以这种方式生成excel状态跟踪器和武器分配。我建议与您的通信有关的TCMax,因为这是国防部使用的程序无论如何。

票数 0
EN
查看全部 1 条回答
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/72010937

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档