Tag Archives: Senha

Word – Recuperando um documento bloqueado quando se perde a senha

Word protegido
Word protegido?

Sempre tomo cuidado com esse tipo de post, dada polêmica que estes geram. Mas o fato é que este não é o primeiro site que vai divulgar esta façanha e nem será o último. Portanto, vamos a ela.

A situação ocorreu recentemente comigo, vindo da digníssima, que protegeu um documento de Word para edição e, claro, depois de um tempo, esqueceu qual era a senha.

Resultado, pediu socorro e fui atrás de saber como é que resolveria o problema (depois de dar uma bela bronca, claro!). Pensei nas soluções ditas “sujas” que normalmente são utilizadas, mas antes disso insisti num método mais limpo, primeiro pela facilidade de aplicá-lo, segundo, para me sentir menos culpado.

😉

Por fim,uma dica no fórum de suporte da própria Microsoft (UAU!) explicava um macete para recuperar o conteúdo do documento, sem vioá-lo. Ou seja, você recupera o trabalho, mas não interfere no arquivo original. Melhor impossível! Como fazer isso?

Supondo que seu arquivo tenha o nome Protegido.docx e ele esteja com a estrutura bloqueada (é esse caso que estamos tratando), basta você abrir o Word num documento em branco, selecionar a opção Inserir->Objeto->Texto do Arquivo. Quando a caixa de diálogo de selecionar arquivo abrir, basta selecionar o local onde está seu arquivo Protegido.docx e clicar em Inserir.

Voilá! Seu documento está lá, com todo conteúdo. O máximo que vai acontecer é alguma perda de formatação, mas em vista do trabalho recuperado, é uma mão na roda!

Bom proveito!

Referência

http://social.technet.microsoft.com/Forums/office/en-US/a60b2669-87f4-4b97-b741-649c6debbe13/how-can-i-unlock-a-protected-document-if-i-forgot-my-password?forum=word

Excel – Desbloqueando Planilhas

Esse é um dos posts “indesejados” por aqueles que trabalham com Excel em seu dia a dia, mas que precisam estar na base de conhecimento de todos eles, pois uma das características de qualquer bom sistema, é saber de suas fragilidades.

O Excel possui nativamente um sistema de proteção de planilhas baseados em senha, mas que é um pouco frágil, do ponto de vista técnico/avançado. Tão frágil que existe um código em VBA que é quase uma convenção entre os programadores da linguagem para desbloquear planilhas de forma rápida. Abaixo segue o mesmo:

Sub DesprotegerEstaPlanilha()
 
    Dim i, i1, i2, i3, i4, i5, i6 As Integer, j As Integer, k As Integer, l As Integer, m As Integer, n As Integer
    On Error Resume Next
    For i = 65 To 66
        For j = 65 To 66
            For k = 65 To 66
                For l = 65 To 66
                    For m = 65 To 66
                        For i1 = 65 To 66
                            For i2 = 65 To 66
                                For i3 = 65 To 66
                                    For i4 = 65 To 66
                                        For i5 = 65 To 66
                                            For i6 = 65 To 66
                                                For n = 32 To 126
                                                    ActiveSheet.Unprotect Chr(i) & Chr(j) & Chr(k) & Chr(l) & Chr(m) & Chr(i1) & Chr(i2) & Chr(i3) & Chr(i4) & Chr(i5) & Chr(i6) & Chr(n)
                                                    If ActiveSheet.ProtectContents = False Then
                                                        MsgBox "Planilha " & ActiveSheet.Name & " debloqueada sob a senha: " & Chr(i) & Chr(j) & _
                                                               Chr(k) & Chr(l) & Chr(m) & Chr(i1) & Chr(i2) & _
                                                               Chr(i3) & Chr(i4) & Chr(i5) & Chr(i6) & Chr(n)
                                                        Exit Sub
                                                    End If
                                                Next
                                            Next
                                        Next
                                    Next
                                Next
                            Next
                        Next
                    Next
                Next
            Next
        Next
    Next
End Sub

O motivo da facilidade do desbloqueio está na simplicidade do algoritmo de encriptação da senha. Conforme anunciado pela própria especificação do Office Open XML specification, a mesma se baseia em um hash de 16 bits. Uma lida rápida em documentações de criptografia nos leva a constatação de que o algoritmo hash produz resultados “sem volta”, ou seja, é impossível obter o valor original a partir de “seu hash”, mas também que a base em 16 bit é quebrável sem muito esforço computacional. A função acima quebra a senha fazendo uso de força bruta, o que comprova a fragilidade do método utilizado.

Disso, dá para tirar algumas conclusões e cuidados que devemos tomar quando falamos de aplicativos e planilhas sérias em nosso dia a dia:

  • Use o recurso de proteção de planilhas somente para bloqueio de nevegação ou algo parecido
  • Se quiser proteger efetivamente, use proteção de senha do arquivo
  • Use senhas fortes sempre que possível

Para projetos VBA:

  • Use sempre proteção de senha para os projetos
  • Siga as dicas deste blog e do nosso fórum sobre técnicas de segurança para projetos VBA

Mais algumas dicas:

http://www.oraxcel.com/projects/encoffice/help/How_safe_is_Excel_encryption.html

Referências


http://kohei.us/2008/01/18/excel-sheet-protection-password-hash/

VBA – Utilizando InputBox com Máscara (senha)

InputBox com Senha
InputBox com Senha

Tirado o blog do Luiz Cláudio que tirou do excelfiles.com. Aí vai mais uma referência.

O InputBox é função extremamente prática para coletar dados de maneira rápida ao usuário. Porém, seria muito bacana se fosse possível estender algumas de suas possbilidades. Uma delas seria se, por exemplo, fosse possível adicionar uma máscara de forma que o usuário pudesse digitar uma senha no InputBox.

Pois bem. A macro abaixo faz exatamente isso:

'////////////////////////////////////////////////////////////////////
'Password masked inputbox
'Allows you to hide characters entered in a VBA Inputbox.
'
'Code written by Daniel Klann
'http://www.danielklann.com/
'March 2003
 
'// Kindly permitted to be amended
'// Amended by Ivan F Moala
'// http://www.xcelfiles.com
'// April 2003
'// Works for Xl2000+ due the AddressOf Operator
'////////////////////////////////////////////////////////////////////
 
'API functions to be used
Private Declare Function CallNextHookEx Lib "user32" (ByVal hHook As Long, _
                                                      ByVal ncode As Long, ByVal wParam As Long, lParam As Any) As Long
 
Private Declare Function GetModuleHandle Lib "kernel32" Alias "GetModuleHandleA" ( _
                                         ByVal lpModuleName As String) As Long
 
Private Declare Function SetWindowsHookEx Lib "user32" Alias "SetWindowsHookExA" ( _
                                          ByVal idHook As Long, ByVal lpfn As Long, ByVal hmod As Long, ByVal dwThreadId As Long) _
                                          As Long
 
Private Declare Function UnhookWindowsHookEx Lib "user32" (ByVal hHook As Long) As Long
 
Private Declare Function SendDlgItemMessage Lib "user32" Alias "SendDlgItemMessageA" ( _
                                            ByVal hDlg As Long, ByVal nIDDlgItem As Long, ByVal wMsg As Long, ByVal wParam As Long, _
                                            ByVal lParam As Long) As Long
 
Private Declare Function GetClassName Lib "user32" Alias "GetClassNameA" (ByVal hWnd As Long, _
                                                                          ByVal lpClassName As String, ByVal nMaxCount As Long) As Long
 
Private Declare Function GetCurrentThreadId Lib "kernel32" () As Long
 
'Constants to be used in our API functions
Private Const EM_SETPASSWORDCHAR = &HCC
Private Const WH_CBT = 5
Private Const HCBT_ACTIVATE = 5
Private Const HC_ACTION = 0
 
Private hHook As Long
 
Public Function NewProc(ByVal lngCode As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
 
    Dim RetVal
    Dim strClassName As String, lngBuffer As Long
 
    If lngCode < HC_ACTION Then
        NewProc = CallNextHookEx(hHook, lngCode, wParam, lParam)
        Exit Function
    End If
 
    strClassName = String$(256, " ")
    lngBuffer = 255
 
    If lngCode = HCBT_ACTIVATE Then    'A window has been activated
        RetVal = GetClassName(wParam, strClassName, lngBuffer)
        If Left$(strClassName, RetVal) = "#32770" Then    'Class name of the Inputbox
            'This changes the edit control so that it display the password character *.
            'You can change the Asc("*") as you please.
            SendDlgItemMessage wParam, &H1324, EM_SETPASSWORDCHAR, Asc("*"), &H0
        End If
    End If
 
    'This line will ensure that any other hooks that may be in place are
    'called correctly.
    CallNextHookEx hHook, lngCode, wParam, lParam
 
End Function
 
'// Make it public = avail to ALL Modules
'// Lets simulate the VBA Input Function
Public Function InputBoxDK(Prompt As String, Optional Title As String, Optional Default As String, _
                           Optional Xpos As Long, Optional Ypos As Long, Optional Helpfile As String, _
                           Optional Context As Long) As String
 
    Dim lngModHwnd As Long, lngThreadID As Long
 
    '// Lets handle any Errors JIC! due to HookProc> App hang!
    On Error GoTo ExitProperly
    lngThreadID = GetCurrentThreadId
    lngModHwnd = GetModuleHandle(vbNullString)
 
    hHook = SetWindowsHookEx(WH_CBT, AddressOf NewProc, lngModHwnd, lngThreadID)
    If Xpos Then
        InputBoxDK = InputBox(Prompt, Title, Default, Xpos, Ypos, Helpfile, Context)
    Else
        InputBoxDK = InputBox(Prompt, Title, Default, , , Helpfile, Context)
    End If
 
ExitProperly:
    UnhookWindowsHookEx hHook
 
End Function

Para fazê-la funcionar, adicione o código acima a um módulo e use a seguinte chamanda:

1
2
3
Sub Teste()
    MsgBox InputBoxDK("Digite sua senha", "Atenção", "123456")
End Sub

Funciona muito bem. Agradecimentos ao autor da macro, o MVP inglês Daniel Klann.

VBA – Abrindo arquivos informando a senha

Esta foi uma pergunta feita num fórum e como é uma informação interessante, resolvi postar aqui.

Muita gente, aliás, todo mundo que trabalha com planilhas no dia a dia costuma proteger os arquivos mais críticos com senha de abertura do arquivo.

Até aí a coisa é simples meso para usuários básicos. Mas quando se quer automatizar este tipo de arquivo com VBA, por exemplo, abrindo-o através de outro arquivo, fica ou pouco complicado. Mas nem tanto.

Se reparar bem, ao ativar no próprio VBA o método Open da coleção Workbooks, será possível ver que um dos parâmetros da função é a senha de abertura do arquivo. O exemplo abaixo abre um arquivo de Excel via VBA:

1
2
3
Sub AbreArquivo()
     Call Workbooks.Open(FileName:="C:\arquivo.xls")
End Sub

Porém, caso o arquivo contenha senha de abertura, bastaria adicionar o seguinte argumento:

1
2
3
4
Sub AbreArquivoComSenha()
     Call Workbooks.Open(FileName:="C:\arquivo.xls", _
     Password:="1234")
End Sub

Para informação, o método devolve um objeto do tipo Workbook que pode ser manipulado depois de aberto.
Isso resolve o problema. Claro, é preciso tomar os devidos cuidados para proteger o projeto VBA e não expor indevidamente a senha para o usuário. Recomenda-se também adicionar um tratamento de erros para inibir ainda mais as mensagens.

Em tempo, a mesma informação é válida para o Word/VBA, porém a coleção utilizada é a Documents e o nome do parâmetro é PasswordDocument. O código abaixo mostra um exemplo da aplicação.

1
2
3
4
Sub AbreDocumentoComSenha()
     Call Documents.Open(FileName:="C:\Documento.doc", _
     PasswordDocument:="1234")
End Sub

Abraços

Tomás